エラーハンドリング

Nuxt でエラーを捕捉して処理する方法を学びます。

Nuxt はフルスタックフレームワークです。つまり、さまざまなコンテキストで発生する、避けられないユーザーランタイムエラーの発生源がいくつかあります

  • Vue レンダリングライフサイクル中のエラー (SSR および CSR)
  • サーバーとクライアントの起動エラー (SSR + CSR)
  • Nitro サーバーライフサイクル中のエラー (server/ ディレクトリ)
  • JS チャンクのダウンロードエラー
SSRServer-Side Rendering (サーバーサイドレンダリング) を、CSRClient-Side Rendering (クライアントサイドレンダリング) を意味します。

Vue エラー

Vue エラーには、以下を使用してフックできます。onErrorCaptured.

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

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

plugins/error-handler.ts
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 フックの処理
  • 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)。
すべての Nuxt ライフサイクルフックを発見してください。

デフォルトのエラーページをカスタマイズするには、アプリケーションのソースディレクトリにある app.vue と並行して ~/error.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">
      Clear errors
    </button>
  </div>
</template>
error.vue とその使用方法の詳細については、こちらをご覧ください。

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

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

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

$routeuseRouter のように、Nuxt プラグインに依存するものをすべて使用する前に確認してください。プラグインがエラーをスローした場合、エラーをクリアするまで再実行されません。
エラーページのレンダリングは完全に別のページロードであり、登録されているミドルウェアは再度実行されます。ミドルウェアで useError を使用して、エラーが処理されているかどうかを確認できます。
Node 16 で実行していて、エラーページをレンダリングするときにクッキーを設定した場合、それらは以前に設定されたクッキーを上書きします。Node 16 は 2023 年 9 月にサポート終了 (EOL) に達したため、より新しいバージョンの Node を使用することをお勧めします。

エラーユーティリティ

useError

TS シグネチャ
function useError (): Ref<Error | { url, statusCode, statusMessage, message, description, data }>

この関数は、現在処理されているグローバル Nuxt エラーを返します。

useError コンポーザブルの詳細については、こちらをご覧ください。

createError

TS シグネチャ
function createError (err: string | { cause, data, message, name, stack, statusCode, statusMessage, fatal }): Error

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

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

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

if (!data.value) {
  throw createError({
    statusCode: 404,
    statusMessage: 'Page Not Found',
  })
}
</script>
createError ユーティリティの詳細については、こちらをご覧ください。

showError

TS シグネチャ
function showError (err: string | Error | { statusCode, statusMessage }): Error

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

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

showError ユーティリティの詳細については、こちらをご覧ください。

clearError

TS シグネチャ
function clearError (options?: { redirect?: string }): Promise<void>

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

clearError ユーティリティの詳細については、こちらをご覧ください。

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

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

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

#error スロットは error をプロパティとして受け取ります。(もし error = null と設定すると、デフォルトスロットの再レンダリングがトリガーされます。最初にエラーが完全に解決されていることを確認する必要があります。そうしないと、エラー スロットが2度レンダリングされるだけになります)。

別のルートに移動すると、エラーは自動的にクリアされます。
app/pages/index.vue
<template>
  <!-- some content -->
  <NuxtErrorBoundary @error="someErrorLogger">
    <!-- You use the default slot to render your content -->
    <template #error="{ error, clearError }">
      You can display the error locally here: {{ error }}
      <button @click="clearError">
        This will clear the error.
      </button>
    </template>
  </NuxtErrorBoundary>
</template>
Docs > 4 X > Examples > Advanced > Error Handling でライブの例を読んで編集してください。