透過 100+ 個技巧學習 Nuxt!

錯誤處理

了解如何在 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
) => {
// 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:createdapp:beforeMount 掛鉤
  • 將您的 Vue 應用程式渲染為 HTML (在 SSR 期間)
  • 掛載應用程式 (在用戶端),儘管您應該使用 onErrorCapturedvue: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 掛鉤)
  • 掛載您的應用程式,如果錯誤沒有被 onErrorCapturedvue:error 掛鉤處理
  • Vue 應用程式在瀏覽器中初始化和掛載 (app:mounted)。
探索所有 Nuxt 生命周期掛鉤。

透過在應用程式的原始碼目錄中新增 ~/error.vue (與 app.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 composable (可以在頁面/元件 setup 函數中呼叫) 或 vue:error 執行階段 nuxt 掛鉤 (可以在 nuxt 插件中設定)。

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

當您準備好移除錯誤頁面時,您可以呼叫 clearError 輔助函數,它接受一個可選的路徑來重新導向 (例如,如果您想導航到 '安全' 頁面)。

在使用任何依賴 Nuxt 插件的東西之前,請務必檢查,例如 $routeuseRouter,因為如果插件拋出錯誤,則在您清除錯誤之前,它不會重新執行。
渲染錯誤頁面是一個完全獨立的頁面載入,這意味著任何已註冊的中介軟體都將再次執行。您可以在中介軟體中使用 useError 來檢查是否正在處理錯誤。
如果您在 Node 16 上執行,並且在渲染錯誤頁面時設定了任何 Cookie,它們將會 覆寫先前設定的 Cookie。我們建議使用較新版本的 Node,因為 Node 16 已於 2023 年 9 月終止生命週期。

錯誤工具

useError

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

此函數將傳回正在處理的全域 Nuxt 錯誤。

閱讀更多關於 useError composable 的資訊。

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 util 的資訊。

showError

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

您可以在用戶端隨時呼叫此函數,或 (在伺服器端) 直接在中介軟體、插件或 setup() 函數中呼叫。它將觸發全螢幕錯誤頁面,您可以使用 clearError 清除它。

建議改為使用 throw createError()

閱讀更多關於 showError util 的資訊。

clearError

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

此函數將清除目前處理的 Nuxt 錯誤。它也接受一個可選的路徑來重新導向 (例如,如果您想導航到 '安全' 頁面)。

閱讀更多關於 clearError util 的資訊。

在元件中渲染錯誤

Nuxt 還提供了一個 <NuxtErrorBoundary> 元件,可讓您在應用程式中處理用戶端錯誤,而無需用錯誤頁面取代整個網站。

此元件負責處理在其預設插槽中發生的錯誤。在用戶端,它將防止錯誤冒泡到頂層,並將改為渲染 #error 插槽。

#error 插槽將接收 error 作為 prop。(如果您設定 error = null,它將觸發重新渲染預設插槽;您需要確保錯誤已完全解決,否則錯誤插槽只會被再次渲染。)

如果您導航到另一個路由,錯誤將自動清除。
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>
文件 > 範例 > 進階 > 錯誤處理 中閱讀和編輯即時範例。