錯誤處理
Nuxt 是一個全端框架,這意味著在不同的上下文中,可能會發生多種無法避免的使用者運行時錯誤
- Vue 渲染生命週期期間的錯誤 (SSR & CSR)
- 伺服器和客戶端啟動錯誤 (SSR + CSR)
- Nitro 伺服器生命週期中的錯誤(
server/
目錄) - 下載 JS 區塊時發生錯誤
Vue 錯誤
您可以使用 onErrorCaptured
來掛鉤 Vue 錯誤。
此外,Nuxt 提供了一個 vue:error
Hook,當任何錯誤傳播到最上層時,將會被呼叫。
如果您正在使用錯誤回報框架,您可以通过 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
Hook 是基於 onErrorCaptured
生命周期 Hook。啟動錯誤
如果 Nuxt 應用程式啟動時發生任何錯誤,Nuxt 將會呼叫 app:error
Hook。
這包括
- 執行 Nuxt 插件
- 處理
app:created
和app:beforeMount
Hook - 將您的 Vue 應用程式渲染成 HTML(在 SSR 期間)
- 掛載應用程式(在用戶端),雖然您應該使用
onErrorCaptured
或vue:error
處理此情況 - 處理
app:mounted
Hook
Nitro 伺服器錯誤
您目前無法為這些錯誤定義伺服器端處理器,但可以渲染錯誤頁面,請參閱 渲染錯誤頁面 部分。
JS 區塊錯誤
您可能會遇到由於網路連線失敗或新部署(使舊的、雜湊的 JS 區塊 URL 無效)而導致的區塊載入錯誤。當在路由導航期間區塊載入失敗時,Nuxt 提供內建的支援,透過執行硬重新載入來處理區塊載入錯誤。
您可以將 experimental.emitRouteChunkError
設定為 false
(完全停用掛鉤這些錯誤)或 manual
(如果您想要自行處理)來變更此行為。如果您想要手動處理區塊載入錯誤,您可以查看 自動實作 以取得想法。
錯誤頁面
fatal: true
建立的錯誤)時,它將會渲染 JSON 回應(如果使用 Accept: application/json
標頭請求)或觸發全螢幕錯誤頁面。當在伺服器生命週期中發生錯誤時,可能是因為
- 處理您的 Nuxt 插件
- 將您的 Vue 應用程式渲染成 HTML
- 伺服器 API 路由拋出錯誤
它也可能在用戶端發生,當
- 處理您的 Nuxt 插件
- 在掛載應用程式之前(
app:beforeMount
Hook) - 如果錯誤沒有使用
onErrorCaptured
或vue:error
Hook 處理,則在掛載您的應用程式時 - 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">Clear errors</button>
</div>
</template>
對於自訂錯誤,我們強烈建議使用 onErrorCaptured
composable(可以在頁面/元件 setup 函式中呼叫)或 vue:error
runtime nuxt hook(可以在 nuxt 插件中設定)。
export default defineNuxtPlugin(nuxtApp => {
nuxtApp.hook('vue:error', (err) => {
//
})
})
當您準備好移除錯誤頁面時,您可以呼叫 clearError
輔助函式,它會接收要重新導向的可選路徑(例如,如果您想要導覽到「安全」頁面)。
$route
或 useRouter
)之前檢查,因為如果插件拋出錯誤,則在您清除錯誤之前它不會重新執行。useError
來檢查是否正在處理錯誤。錯誤工具
useError
function useError (): Ref<Error | { url, statusCode, statusMessage, message, description, data }>
此函式將會傳回正在處理的全域 Nuxt 錯誤。
createError
function createError (err: string | { cause, data, message, name, stack, statusCode, statusMessage, fatal }): Error
建立具有其他中繼資料的錯誤物件。您可以傳遞字串以設定為錯誤的 message
,或傳遞包含錯誤屬性的物件。它可以在您應用程式的 Vue 和伺服器部分使用,並且旨在被拋出。
如果您拋出使用 createError
建立的錯誤
- 在伺服器端,它將會觸發全螢幕錯誤頁面,您可以使用
clearError
清除它。 - 在用戶端,它將會拋出非嚴重錯誤供您處理。如果您需要觸發全螢幕錯誤頁面,則可以透過設定
fatal: true
來執行此操作。
<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>
showError
function showError (err: string | Error | { statusCode, statusMessage }): Error
您可以在用戶端的任何時間點呼叫此函式,或(在伺服器端)直接在中介軟體、插件或 setup()
函式中呼叫。它將會觸發全螢幕錯誤頁面,您可以使用 clearError
清除它。
建議改為使用 throw createError()
。
clearError
function clearError (options?: { redirect?: string }): Promise<void>
此函式將會清除目前處理的 Nuxt 錯誤。它也會接收要重新導向的可選路徑(例如,如果您想要導覽到「安全」頁面)。
在元件中渲染錯誤
Nuxt 也提供了一個 <NuxtErrorBoundary>
元件,可讓您在應用程式中處理用戶端錯誤,而無需將整個網站替換為錯誤頁面。
此元件負責處理其預設插槽內發生的錯誤。在用戶端,它將會防止錯誤冒泡到最上層,並改為渲染 #error
插槽。
#error
插槽將會接收 error
作為 prop。(如果您設定 error = null
,它將會觸發重新渲染預設插槽;您需要確保錯誤已完全解決,否則錯誤插槽只會被渲染第二次。)
<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>