AI 應用元件

錯誤堆疊檢視器

錯誤堆疊檢視器:逐幀列出呼叫位置,高亮使用者程式碼、摺疊第三方框架幀,可展開單幀看原始碼片段並一鍵複製。

給 AI 程式助理、除錯面板與錯誤回報頁使用的堆疊檢視器。傳入結構化的 frames,或直接丟一段原始堆疊字串給 raw——內建的 parseStack 會解析 at fn (file:line:col) 與 fn@file:line:col 兩種常見格式,解析不了的行保留為純文字。使用者程式碼以左側色帶與「你的程式碼」小籤標出,連續的第三方框架幀摺成一列「⋯ 3 個框架內部呼叫」;展開單幀可看原始碼片段,出錯行整行上色並在欄位處畫出 ^ 指示。右上角一鍵複製整段堆疊,支援原始格式與 Markdown。

把這個效果裝進你的專案

在專案資料夾執行指令,CLI 會加入原始碼與依賴套件,再依下方使用範例引用元件。

npx webberui@latest add stack-trace-viewer

還沒有專案,或安裝遇到問題?看快速開始 →

Playground

即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。

180
編輯中的呼叫預設屬性
<StackTraceViewer/>

完整範例包含預覽的排版與資料。先安裝元件,再把範例檔貼入你的專案。

安裝

npx webberui@latest add https://webberui.com/r/stack-trace-viewer.json

或在 components.json 設定 registries 後,改用 @webberui/stack-trace-viewer 安裝。

使用

import { StackTraceViewer } from "@/components/ui/stack-trace-viewer";

// 直接傳原始堆疊字串
<StackTraceViewer
  error={{ name: err.name, message: err.message }}
  raw={err.stack}
  onFrameClick={(frame) => openInEditor(frame.file, frame.line)}
/>

// 或傳結構化 frames(可附原始碼片段)
<StackTraceViewer
  error={{ name: "TypeError", message: "Cannot read properties of undefined (reading 'amount')" }}
  frames={[
    {
      fn: "formatPrice",
      file: "src/lib/price.ts",
      line: 42,
      column: 29,
      snippet: { startLine: 41, lines: ["  const rate = item.taxRate ?? 0.05;", "  const off = item.discount.amount;"] },
    },
    { fn: "beginWork", file: "node_modules/ui-runtime/dist/render.js", line: 2210, column: 14 },
  ]}
  copyFormat="markdown"
/>

Props

Prop型別預設值說明
errorStackTraceError—錯誤標頭:類型與訊息
framesStackFrame[]—結構化的堆疊幀;提供時優先於 raw
rawstring—原始堆疊文字,以內建 parseStack 解析
isUserFrame(frame: StackFrame) => boolean見說明判斷是否為使用者程式碼;預設為 file 不含 node_modules、不以 node: 開頭、不含 internal/
defaultExpanded"first-user" | "none" | "all""first-user"非受控模式的初始展開策略:展開第一個使用者幀/全收合/全展開
expandedstring[]—受控的展開幀 id 清單;未提供時由元件內部管理
onExpandedChange(ids: string[]) => void—展開清單變動時回呼
collapseLibrarybooleantrue是否把連續的第三方框架幀(兩幀以上)摺成一列
onFrameClick(frame: StackFrame) => void—點擊(或以 Enter/Space 啟動)幀列時回呼,例如在編輯器開啟
copyFormat"raw" | "markdown""raw"複製鈕輸出的格式
maxHeightnumber | string420幀列表最大高度,超出時內部捲動;數字視為 px
durationnumber180展開動畫時長(毫秒),同時寫入 --wb-stack-trace-viewer-duration
classNamestring—透傳到最外層容器

StackFrame

欄位型別預設值說明
idstring—穩定識別碼;未提供時以索引產生(frame-0、frame-1…),expanded 用的就是這個值
fnstring—函式名稱;沒有時顯示「(匿名)」
filestring—檔案路徑
linenumber—行號(從 1 起算)
columnnumber—欄位(從 1 起算),用來在出錯行畫 ^ 指示
isUserboolean—明確標記是否為使用者程式碼;未提供時交給 isUserFrame
snippetStackFrameSnippet—原始碼片段;沒有時展開區顯示「沒有可用的原始碼」
textstring—解析不了的原始行(此時 file 為空字串、line 為 0),以純文字列呈現

StackFrameSnippet

欄位型別預設值說明
startLinenumber—片段第一行在原始檔中的行號
linesstring[]—片段內容,一個元素一行

StackTraceError

欄位型別預設值說明
namestring—錯誤類型,例如 TypeError
messagestring—錯誤訊息,可換行

另外具名匯出 parseStack(raw)、formatStackTrace(error, frames, format)、formatFrameLocation(frame) 與 defaultIsUserFrame(frame),方便在伺服器端或錯誤回報流程重複使用同一套解析與輸出邏輯。

細節

  • 解析:第一個非空行若不是幀(通常是 TypeError: … 標頭)會被略過;其餘解析不了的行保留為純文字幀,不會默默消失。
  • 摺疊:只有連續兩幀以上的第三方幀會摺成一列——單獨一幀摺起來並不省空間。點開後各幀以 20ms 間隔依序淡入,焦點移到群組第一幀。
  • 路徑截斷:路徑太長時截斷的是目錄段,檔名與行列號永遠保留,效果等同中間截斷;完整路徑在 title 提示中。
  • 原始碼片段不做語法高亮,只用 neutral 色階,裝進任何站都不會和既有的程式碼主題打架。
  • 複製:成功時圖示交叉淡接為勾勾 1.5 秒;瀏覽器不允許存取剪貼簿時,改為展開一個已選取文字的唯讀欄位,提示使用者手動按 Ctrl+C/⌘C。
  • 節奏變數:--wb-stack-trace-viewer-duration(箭頭旋轉,預設 180ms,由 duration 寫入);使用者幀色帶可用 --wb-stack-trace-viewer-accent 覆寫。

可及性

  • 整體為 role="region"、aria-label="錯誤堆疊",幀列表使用有序清單 ol 語意
  • 每幀是原生 button,帶 aria-expanded 與 aria-controls,aria-label 完整描述幀,例如「第 3 幀:CartSummary,位於 src/components/cart-summary.tsx 第 27 行,你的程式碼」
  • 鍵盤:列表採 roving tabindex,只佔一個 Tab 停駐點;↑/↓ 在幀列之間移動、Home/End 跳到首尾、Enter/Space 展開收合、→ 展開、← 收合、C 複製聚焦幀的位置(Ctrl/⌘+C 保留給瀏覽器)
  • 摺疊列與複製鈕皆為原生 button;複製結果透過 aria-live="polite" 宣告「已複製」
  • 出錯行對螢幕閱讀器額外朗讀「出錯行」,裝飾性的行號欄與 ^ 指示對輔助科技隱藏
  • 使用者系統開啟「減少動態效果」時,展開直接出現、摺疊列不做依序淡入、複製鈕圖示直接替換