エラー処理
Nuxtでエラーをキャッチして処理する方法を学びます。
Nuxtはフルスタックフレームワークであるため、異なるコンテキストで発生する可能性のあるいくつかの予防不能なユーザーランタイムエラーの原因がいくつかあります:
- Vueレンダリングライフサイクル中に発生するエラー(SSR & CSR)
- サーバーおよびクライアントの起動エラー(SSR + CSR)
- Nitroサーバーライフサイクル中のエラー(
server/
ディレクトリ) - JSチャンクのダウンロードエラー
SSRはServer-Side Rendering(サーバーサイドレンダリング)の略であり、CSRはClient-Side Rendering(クライアントサイドレンダリング)の略です。
Vueエラー
Vueのエラーに関しては、onErrorCaptured
を使用してフックことができます。
加えて、Nuxtはトップレベルまでエラーが伝播した場合に呼ばれるvue:error
フックを提供しています。
エラー報告フレームワークを使用している場合は、vueApp.config.errorHandler
を通じてグローバルハンドラーを提供することができます。これは処理されたものを含むすべてのVueエラーを受け取ります。
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.config.errorHandler = (error, instance, info) => {
// handle error, e.g. report to a service
}
// Also possible
nuxtApp.hook('vue:error', (error, instance, info) => {
// handle error, e.g. report to a service
})
})
vue:error
フックは、onErrorCaptured
ライフサイクルフックに基づいています。
起動エラー
Nuxtアプリケーションの起動中にエラーが発生した場合、Nuxtはapp:error
フックを呼びます。
これには以下が含まれます:
- Nuxtプラグインの実行
app:created
およびapp:beforeMount
フックの処理- HTMLへのVueアプリのレンダリング(SSR中)
- アプリのマウント(クライアントサイド)、ただし、この場合は
onErrorCaptured
またはvue:error
で処理する必要があります app:mounted
フックの処理
Nitroサーバーエラー
現在、これらのエラーのサーバーサイドハンドラーを定義することはできませんが、エラーページをレンダリングすることができます。詳細についてはエラーページをレンダリングするセクションをご覧ください。
JSチャンクのエラー
ネットワーク接続の障害や新しいデプロイメント(古いハッシュ化されたJSチャンクURLを無効にする)により、チャンク読み込みのエラーが発生することがあります。Nuxtはルートナビゲーション中にチャンクの読み込みに失敗した場合、ハードリロードを実行することにより、チャンク読み込みエラーを処理するための組込みサポートを提供しています。
この挙動を変更するには、experimental.emitRouteChunkError
をfalse
に設定する(これらのエラーをまったくフックしないようにするため)か、それらを自分で処理したい場合はmanual
に設定します。チャンクの読み込みエラーを手動で処理したい場合は、自動実装例を参考にすることができます。
エラーページ
Nuxtが致命的なエラー(サーバー上の処理されていないエラー、またはクライアント上でfatal: true
で作成されたエラー)に遭遇した場合、Accept: application/json
ヘッダーで要求された場合はJSONレスポンスをレンダリングするか、全画面のエラーページをトリガーします。
サーバーライフサイクル中にエラーが発生する場合があります:
- Nuxtプラグインの処理中
- HTMLへのVueアプリのレンダリング中
- サーバー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
ランタイムフックを使用することを強く推奨します。
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
追加のメタデータを持つエラーオブジェクトを作成します。エラーmessage
として設定される文字列を渡すことも、エラープロパティを含むオブジェクトを渡すこともできます。この関数はアプリの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: 'Page Not Found'
})
}
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>
<!-- some content -->
<NuxtErrorBoundary @error="someErrorLogger">
<!-- You use the default slot to render your content -->
<template #error="{ error, clearError }">
エラーをここにローカルで表示: {{ error }}
<button @click="clearError">
これによりエラーがクリアされます。
</button>
</template>
</NuxtErrorBoundary>
</template>
※このページは Nuxt.js 公式ドキュメントの翻訳ページ(非公式)です。
公式ドキュメントの該当ページはこちら:
https://nuxt.com/docs/3.x/getting-started/error-handling