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