interface ClientErrorPayload { message: string; stack?: string; url?: string; line?: number; column?: number; userAgent?: string; tags?: string[]; } let reportEndpoint = "/api/_error-report"; function reportError(payload: ClientErrorPayload) { try { $fetch(reportEndpoint, { method: "POST", body: payload, }).catch(() => {}); } catch { // 静默失败,避免错误上报本身导致循环 } } export default defineNuxtPlugin((nuxtApp) => { // Vue 运行时错误 nuxtApp.vueApp.config.errorHandler = (err, _instance, info) => { const error = err instanceof Error ? err : new Error(String(err)); reportError({ message: error.message, stack: error.stack, url: window.location.href, userAgent: navigator.userAgent, tags: ["vue", info], }); }; // 未捕获的 Promise rejection window.addEventListener("unhandledrejection", (event) => { const reason = event.reason; const error = reason instanceof Error ? reason : new Error(String(reason)); reportError({ message: error.message, stack: error.stack, url: window.location.href, userAgent: navigator.userAgent, tags: ["unhandledrejection"], }); }); // 未捕获的同步错误 window.addEventListener("error", (event) => { if (!event.message) return; reportError({ message: event.message, url: event.filename || window.location.href, line: event.lineno, column: event.colno, userAgent: navigator.userAgent, tags: ["window"], }); }); });