Frontend Lab
← 回到所有模式
PD07📊 Data Display · 資料展示錯誤

Error Boundary

錯誤邊界

難度 ★★★★★標籤 error · retry · fallback3 min read

模式簡述

Error Boundary:UI 出錯時的 fallback。React 的 error boundary 概念延伸。要給使用者「再試一次」的選項。

✓ 子元件渲染正常

正常|子元件正常渲染

Claude Code Prompt

💬 Claude Code Prompt
參考:PD07 error-boundary
組件:ErrorBoundary.tsx

Error Boundary:UI 出錯時的 fallback。React 的 error boundary 概念延伸。要給使用者「再試一次」的選項。

限制:
- 只說「出錯了」
- 自動重試到死
- 錯誤訊息太技術

完整程式碼

ErrorBoundary.tsx
"use client";
import { AlertTriangle, RotateCcw } from "lucide-react";

type State = "ok" | "error";

export function ErrorBoundary({ state = "error" }: { state?: State }) {
if (state === "ok") {
  return (
    <div className="grid w-full max-w-md place-items-center rounded-lg border border-border bg-background/30 px-6 py-12">
      <p className="font-mono text-xs text-muted-foreground">
        ✓ 子元件渲染正常
      </p>
    </div>
  );
}
return (
  <div className="w-full max-w-md rounded-lg border border-red-500/30 bg-red-500/5 p-5">
    <div className="flex items-start gap-3">
      <AlertTriangle className="mt-0.5 h-5 w-5 shrink-0 text-red-500" />
      <div className="flex-1">
        <h3 className="text-sm font-medium text-foreground">這個區塊出錯了</h3>
        <p
          className="mt-1 text-xs text-muted-foreground"
          style={{ fontFamily: "var(--font-zh)" }}
        >
          其他區塊不受影響。可以點下方按鈕重試載入。
        </p>
        <details className="mt-2 cursor-pointer">
          <summary className="font-mono text-[10px] text-muted-foreground/70 hover:text-foreground">
            展開錯誤訊息
          </summary>
          <pre className="mt-1.5 overflow-x-auto rounded bg-background/50 p-2 font-mono text-[10px] text-red-400">
            TypeError: Cannot read properties of undefined (reading 'map')
              at PatternList (PatternList.tsx:42)
          </pre>
        </details>
        <button className="mt-3 inline-flex items-center gap-1.5 rounded-md border border-border bg-background px-3 py-1.5 font-mono text-xs hover:border-lab-accent">
          <RotateCcw className="h-3 w-3" />
          重試
        </button>
      </div>
    </div>
  </div>
);
}

何時用

  • ✅ 獨立 widget/section 出錯時局部 fallback
  • ✅ 整頁 crash 時的 fallback page
  • ✅ API fail 後的 retry UI

何時別用

  • ❌ 錯誤是使用者操作造成(用 inline validation)
  • ❌ 錯誤是預期內的空狀態(用 empty state)
  • ❌ 需要登入但沒登入(用 auth gate)

我踩過的坑

  1. 只說「出錯了」:使用者完全不知道怎麼辦。給 error code + 重試按鈕 + 聯絡支援連結。

  2. 自動重試到死:API fail 不要 retry 5 次。手動由使用者觸發。

  3. 錯誤訊息太技術:‘ECONNREFUSED’ 一般人看不懂。轉成「無法連線伺服器」。

相關模式

  • PD05

搜尋

按 ⌘K 隨時開啟