エラーハンドリング
Nuxtでエラーをキャッチして処理する方法を学びます。
Nuxtはフルスタックフレームワークであるため、さまざまなコンテキストで発生する防ぎようのないユーザーランタイムエラーのいくつかの原因があります:
- Vueのレンダリングライフサイクル中のエラー(SSR & CSR)
- サーバーおよびクライアントの起動エラー(SSR + CSR)
- Nitroサーバーライフサイクル中のエラー(
server/
ディレクトリ) - JSチャンクのダウンロードエラー
SSRはサーバーサイドレンダリング、CSRはクライアントサイドレンダリングの略です。
Vueのエラー
onErrorCaptured
を使用して、Vueのエラーにフックすることができます。
さらに、Nuxtはvue:error
フックを提供しており、エラーがトップレベルまで伝播した場合に呼び出されます。
エラーレポートフレームワークを使用している場合は、vueApp.config.errorHandler
を通じてグローバルハンドラーを提供できます。これにより、処理された場合でもすべてのVueエラーを受け取ります。
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.config.errorHandler = (error, instance, info) => {
// エラーを処理、例:サービスに報告
}
// これも可能
nuxtApp.hook('vue:error', (error, instance, info) => {
// エラーを処理、例:サービスに報告
})
})
vue:error
フックはonErrorCaptured
ライフサイクルフックに基づいています。
起動エラー
Nuxtアプリケーションの起動時にエラーが発生した場合、app:error
フックが呼び出されます。
これには以下が含まれます:
- Nuxtプラグインの実行
app:created
およびapp:beforeMount
フックの処理- VueアプリのHTMLへのレンダリング(SSR中)
- アプリのマウント(クライアントサイド)、ただしこのケースは
onErrorCaptured
またはvue:error
で処理する必要があります app:mounted
フックの処理
Nitroサーバーエラー
これらのエラーに対するサーバーサイドハンドラーを現在定義することはできませんが、エラーページをレンダリングすることができます。エラーページのレンダリングセクションを参照してください。
JSチャンクのエラー
ネットワーク接続の失敗や新しいデプロイメント(古いハッシュ付きJSチャンクURLを無効にする)により、チャンクの読み込みエラーが発生する可能性があります。Nuxtは、ルートナビゲーション中にチャンクの読み込みが失敗した場合にハードリロードを実行することで、チャンク読み込みエラーの処理をサポートしています。
この動作を変更するには、experimental.emitRouteChunkError
をfalse
に設定して(これらのエラーにフックしないようにする)、または自分で処理したい場合はmanual
に設定します。チャンク読み込みエラーを手動で処理したい場合は、自動実装を参考にしてください。
エラーページ
Nuxtが致命的なエラー(サーバー上の未処理のエラー、またはクライアント上でfatal: true
として作成されたエラー)に遭遇した場合、JSONレスポンスをレンダリングする(Accept: application/json
ヘッダーで要求された場合)か、フルスクリーンのエラーページをトリガーします。
サーバーライフサイクル中にエラーが発生する可能性があります:
- Nuxtプラグインの処理中
- VueアプリのHTMLへのレンダリング中
- サーバーAPIルートがエラーをスローした場合
クライアントサイドでも発生する可能性があります:
- Nuxtプラグインの処理中
- アプリケーションのマウント前(
app:beforeMount
フック) - エラーが
onErrorCaptured
またはvue:error
フックで処理されなかった場合のアプリのマウント中 - Vueアプリがブラウザで初期化およびマウントされたとき(
app:mounted
)。
デフォルトのエラーページをカスタマイズするには、アプリケーションのソースディレクトリに~/error.vue
をapp.vue
と一緒に追加します。
<script setup lang="ts">
import type { NuxtError } from '#app'
const props = defineProps({
error: Object as () => NuxtError
})
const handleError = () => clearError({ redirect: '/' })
</script>
<template>
<div>
<h2>{{ error?.statusCode }}</h2>
<button @click="handleError">エラーをクリア</button>
</div>
</template>
カスタムエラーには、ページ/コンポーネントのセットアップ関数で呼び出すことができるonErrorCaptured
コンポーザブルや、Nuxtプラグインで設定できるvue:error
ランタイムNuxtフックを使用することを強くお勧めします。
export default defineNuxtPlugin(nuxtApp => {
nuxtApp.hook('vue:error', (err) => {
//
})
})
エラーページを削除する準備ができたら、オプションでリダイレクトするパスを指定できるclearError
ヘルパー関数を呼び出すことができます(たとえば、「安全な」ページに移動したい場合)。
Nuxtプラグインに依存するもの($route
やuseRouter
など)を使用する前に必ず確認してください。プラグインがエラーをスローした場合、エラーをクリアするまで再実行されません。
エラーページのレンダリングは完全に別のページロードであり、登録されたミドルウェアが再度実行されます。ミドルウェアでuseError
を使用してエラーが処理されているかどうかを確認できます。
Node 16で実行していて、エラーページをレンダリングする際にクッキーを設定した場合、それらは以前に設定されたクッキーを上書きします。Node 16は2023年9月にサポート終了となったため、新しいバージョンのNodeを使用することをお勧めします。
エラーユーティリティ
useError
function useError (): Ref<Error | { url, statusCode, statusMessage, message, description, data }>
この関数は、処理中のグローバルNuxtエラーを返します。
こちらも参照 api > composables > use-errorcreateError
function createError (err: string | { cause, data, message, name, stack, statusCode, statusMessage, fatal }): Error
追加のメタデータを持つエラーオブジェクトを作成します。エラーメッセージとして設定する文字列またはエラーのプロパティを含むオブジェクトを渡すことができます。これは、アプリのVue部分とサーバー部分の両方で使用可能で、スローすることを意図しています。
createError
で作成されたエラーをスローすると:
- サーバーサイドでは、フルスクリーンのエラーページをトリガーし、
clearError
でクリアできます。 - クライアントサイドでは、処理するための非致命的なエラーをスローします。フルスクリーンのエラーページをトリガーする必要がある場合は、
fatal: true
を設定することでこれを行うことができます。
const route = useRoute()
const { data } = await useFetch(`/api/movies/${route.params.slug}`)
if (!data.value) {
throw createError({
statusCode: 404,
statusMessage: 'ページが見つかりません'
})
}
showError
function showError (err: string | Error | { statusCode, statusMessage }): Error
この関数は、クライアントサイドの任意のポイント、または(サーバーサイドでは)ミドルウェア、プラグイン、setup()
関数内で直接呼び出すことができます。これにより、clearError
でクリアできるフルスクリーンのエラーページがトリガーされます。
代わりにthrow createError()
を使用することをお勧めします。
clearError
function clearError (options?: { redirect?: string }): Promise<void>
この関数は、現在処理中のNuxtエラーをクリアします。また、オプションでリダイレクトするパスを指定できます(たとえば、「安全な」ページに移動したい場合)。
こちらも参照 api > utils > clear-errorコンポーネントでのエラーのレンダリング
Nuxtは、アプリ内でクライアントサイドのエラーを処理し、サイト全体をエラーページに置き換えることなく処理できる<NuxtErrorBoundary>
コンポーネントも提供しています。
このコンポーネントは、そのデフォルトスロット内で発生するエラーを処理する責任を負います。クライアントサイドでは、エラーがトップレベルに伝播するのを防ぎ、代わりに#error
スロットをレンダリングします。
#error
スロットは、error
をプロップとして受け取ります。(error = null
を設定すると、デフォルトスロットの再レンダリングがトリガーされます。エラーが完全に解決されるまで、エラースロットが再度レンダリングされるだけです。)
別のルートに移動すると、エラーは自動的にクリアされます。
<template>
<!-- 一部のコンテンツ -->
<NuxtErrorBoundary @error="someErrorLogger">
<!-- デフォルトスロットを使用してコンテンツをレンダリングします -->
<template #error="{ error, clearError }">
ここでエラーをローカルに表示できます: {{ error }}
<button @click="clearError">
これでエラーがクリアされます。
</button>
</template>
</NuxtErrorBoundary>
</template>
※このページは Nuxt.js 公式ドキュメントの翻訳ページ(非公式)です。
公式ドキュメントの該当ページはこちら:
https://nuxt.com/docs/4.x/getting-started/error-handling