當網站出錯時 (致命錯誤處理)
再完美的程式碼也可能出錯。網路可能中斷、API 可能掛掉。當這些讓網站無法正常運作的「致命錯誤」發生時,我們需要給使用者一個友善的提示,而不是一個冰冷的白畫面或錯誤碼。
1. 網站的「維修中」告示牌:error.vue
當 Nuxt 遇到一個無法處理的致命錯誤時,它會放棄渲染當前的頁面,轉而尋找一個名為 error.vue
的特殊檔案,並顯示它的內容。
您可以把它想像成是商店發生緊急狀況時,掛在外面的「今日盤點,暫停營業」的告示牌。
如何建立這個告示牌?
在您專案的根目錄(與 app.vue
同層)建立一個 error.vue
檔案。
這個元件會自動接收一個名為 error
的 prop,裡面包含了錯誤的詳細資訊,例如 statusCode
(404, 500) 和 statusMessage
。
<script setup>
// Nuxt 會自動把 error 物件傳進來
defineProps({
error: Object
});
// 點擊按鈕時,清除錯誤並導回首頁
const handleError = () => clearError({ redirect: '/' });
</script>
<template>
<div class="error-page">
<h1>Oops!</h1>
<h2>{{ error.statusCode }} - {{ error.statusMessage }}</h2>
<p>抱歉,頁面似乎走失了。</p>
<button @click="handleError">回到首頁</button>
</div>
</template>
2. 如何手動掛上告示牌:throw createError()
有時候,錯誤不是 Nuxt 自動發現的,而是我們在程式邏輯中判斷出來的。例如,使用者想看一篇文章,但資料庫裡根本沒有這篇文章。
這時,我們需要主動告訴 Nuxt:「嘿,這裡出大問題了,快顯示錯誤頁面!」
最推薦的方法就是使用 throw createError()
。
最常見的情境:useFetch 後發現找不到資料
<script setup>
const route = useRoute();
const { data: post } = await useFetch(`/api/posts/${route.params.id}`);
// 如果 API 回傳的 post 是 null 或 undefined,就代表找不到這篇文章
if (!post.value) {
throw createError({
statusCode: 404,
statusMessage: '文章不存在 (Article Not Found)',
fatal: true // fatal: true 會確保觸發全螢幕的 error.vue
});
}
</script>
當這段程式碼被執行時,Nuxt 就會立刻停止當前頁面的渲染,轉而去顯示我們設計好的 error.vue。
3. 如何撕掉告示牌:clearError()
clearError()
是一個內建的工具函式,它的作用就是清除當前的錯誤狀態,並可選擇性地將使用者導向一個安全的頁面(通常是首頁)。這就是我們在 error.vue
的按鈕上綁定的函式。
// 清除錯誤並重新導向
const handleError = () => {
clearError({
redirect: '/' // 導向首頁
});
}
// 或者只是清除錯誤,留在當前頁面
const handleRetry = () => {
clearError();
}
今日總結
今天我們學會了如何處理最嚴重的錯誤情況:
建立一個客製化的 error.vue 頁面,提供友善的錯誤提示。
學會如何使用 throw createError() 在適當時機主動觸發錯誤頁面。
使用 clearError() 讓使用者能從錯誤中恢復,並回到網站。
預告:但不是所有錯誤都這麼嚴重。如果只是頁面中的某個小元件出錯,我們不希望它影響到整個頁面,該怎麼辦呢?明天,我們將學習如何處理這種「局部錯誤」。