nuxt logo

ドキュメント翻訳(非公式)

エラーハンドリング

Nuxtでエラーをキャッチして処理する方法を学びます。

Nuxtはフルスタックフレームワークであるため、さまざまなコンテキストで発生する防ぎようのないユーザーランタイムエラーのいくつかの原因があります:

  • Vueのレンダリングライフサイクル中のエラー(SSR & CSR)
  • サーバーおよびクライアントの起動エラー(SSR + CSR)
  • Nitroサーバーライフサイクル中のエラー(server/ ディレクトリ)
  • JSチャンクのダウンロードエラー

SSRサーバーサイドレンダリングCSRクライアントサイドレンダリングの略です。

Vueのエラー

onErrorCapturedを使用して、Vueのエラーにフックすることができます。

さらに、Nuxtはvue:errorフックを提供しており、エラーがトップレベルまで伝播した場合に呼び出されます。

エラーレポートフレームワークを使用している場合は、vueApp.config.errorHandlerを通じてグローバルハンドラーを提供できます。これにより、処理された場合でもすべてのVueエラーを受け取ります。

plugins/error-handler.ts
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.emitRouteChunkErrorfalseに設定して(これらのエラーにフックしないようにする)、または自分で処理したい場合はmanualに設定します。チャンク読み込みエラーを手動で処理したい場合は、自動実装を参考にしてください。

エラーページ

Nuxtが致命的なエラー(サーバー上の未処理のエラー、またはクライアント上でfatal: trueとして作成されたエラー)に遭遇した場合、JSONレスポンスをレンダリングする(Accept: application/jsonヘッダーで要求された場合)か、フルスクリーンのエラーページをトリガーします。

サーバーライフサイクル中にエラーが発生する可能性があります:

  • Nuxtプラグインの処理中
  • VueアプリのHTMLへのレンダリング中
  • サーバーAPIルートがエラーをスローした場合

クライアントサイドでも発生する可能性があります:

  • Nuxtプラグインの処理中
  • アプリケーションのマウント前(app:beforeMountフック)
  • エラーがonErrorCapturedまたはvue:errorフックで処理されなかった場合のアプリのマウント中
  • Vueアプリがブラウザで初期化およびマウントされたとき(app:mounted)。
こちらも参照 api > advanced > hooks

デフォルトのエラーページをカスタマイズするには、アプリケーションのソースディレクトリに~/error.vueapp.vueと一緒に追加します。

error.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>
こちらも参照 guide > directory-structure > error

カスタムエラーには、ページ/コンポーネントのセットアップ関数で呼び出すことができるonErrorCapturedコンポーザブルや、Nuxtプラグインで設定できるvue:errorランタイムNuxtフックを使用することを強くお勧めします。

plugins/error-handler.ts
export default defineNuxtPlugin(nuxtApp => {
  nuxtApp.hook('vue:error', (err) => {
    //
  })
})

エラーページを削除する準備ができたら、オプションでリダイレクトするパスを指定できるclearErrorヘルパー関数を呼び出すことができます(たとえば、「安全な」ページに移動したい場合)。

Nuxtプラグインに依存するもの($routeuseRouterなど)を使用する前に必ず確認してください。プラグインがエラーをスローした場合、エラーをクリアするまで再実行されません。

エラーページのレンダリングは完全に別のページロードであり、登録されたミドルウェアが再度実行されます。ミドルウェアでuseErrorを使用してエラーが処理されているかどうかを確認できます。

Node 16で実行していて、エラーページをレンダリングする際にクッキーを設定した場合、それらは以前に設定されたクッキーを上書きします。Node 16は2023年9月にサポート終了となったため、新しいバージョンのNodeを使用することをお勧めします。

エラーユーティリティ

useError

TS Signature
function useError (): Ref<Error | { url, statusCode, statusMessage, message, description, data }>

この関数は、処理中のグローバルNuxtエラーを返します。

こちらも参照 api > composables > use-error

createError

TS Signature
function createError (err: string | { cause, data, message, name, stack, statusCode, statusMessage, fatal }): Error

追加のメタデータを持つエラーオブジェクトを作成します。エラーメッセージとして設定する文字列またはエラーのプロパティを含むオブジェクトを渡すことができます。これは、アプリのVue部分とサーバー部分の両方で使用可能で、スローすることを意図しています。

createErrorで作成されたエラーをスローすると:

  • サーバーサイドでは、フルスクリーンのエラーページをトリガーし、clearErrorでクリアできます。
  • クライアントサイドでは、処理するための非致命的なエラーをスローします。フルスクリーンのエラーページをトリガーする必要がある場合は、fatal: trueを設定することでこれを行うことができます。
pages/movies/[slug\
const route = useRoute()
const { data } = await useFetch(`/api/movies/${route.params.slug}`)

if (!data.value) {
  throw createError({
    statusCode: 404,
    statusMessage: 'ページが見つかりません'
  })
}
こちらも参照 api > utils > create-error

showError

TS Signature
function showError (err: string | Error | { statusCode, statusMessage }): Error

この関数は、クライアントサイドの任意のポイント、または(サーバーサイドでは)ミドルウェア、プラグイン、setup()関数内で直接呼び出すことができます。これにより、clearErrorでクリアできるフルスクリーンのエラーページがトリガーされます。

代わりにthrow createError()を使用することをお勧めします。

こちらも参照 api > utils > show-error

clearError

TS Signature
function clearError (options?: { redirect?: string }): Promise<void>

この関数は、現在処理中のNuxtエラーをクリアします。また、オプションでリダイレクトするパスを指定できます(たとえば、「安全な」ページに移動したい場合)。

こちらも参照 api > utils > clear-error

コンポーネントでのエラーのレンダリング

Nuxtは、アプリ内でクライアントサイドのエラーを処理し、サイト全体をエラーページに置き換えることなく処理できる<NuxtErrorBoundary>コンポーネントも提供しています。

このコンポーネントは、そのデフォルトスロット内で発生するエラーを処理する責任を負います。クライアントサイドでは、エラーがトップレベルに伝播するのを防ぎ、代わりに#errorスロットをレンダリングします。

#errorスロットは、errorをプロップとして受け取ります。(error = nullを設定すると、デフォルトスロットの再レンダリングがトリガーされます。エラーが完全に解決されるまで、エラースロットが再度レンダリングされるだけです。)

別のルートに移動すると、エラーは自動的にクリアされます。

app/pages/index.vue
<template>
  <!-- 一部のコンテンツ -->
  <NuxtErrorBoundary @error="someErrorLogger">
    <!-- デフォルトスロットを使用してコンテンツをレンダリングします -->
    <template #error="{ error, clearError }">
      ここでエラーをローカルに表示できます: {{ error }}
      <button @click="clearError">
        これでエラーがクリアされます。
      </button>
    </template>
  </NuxtErrorBoundary>
</template>
サンプルコードの編集とプレビューexamples > advanced > error-handling