You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

62 lines
1.5 KiB

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"],
});
});
});