1.5 KB56 lines
Blame
1"use client";
2
3import { useEffect } from "react";
4
5export function DevErrorReporter() {
6 useEffect(() => {
7 if (process.env.NODE_ENV === "production") return;
8
9 const originalError = console.error;
10 const originalWarn = console.warn;
11
12 function report(type: string, args: unknown[]) {
13 const message = args
14 .map((a) => (typeof a === "string" ? a : JSON.stringify(a, null, 2)))
15 .join(" ")
16 .slice(0, 4000);
17
18 fetch("/api/dev-errors", {
19 method: "POST",
20 headers: { "Content-Type": "application/json" },
21 body: JSON.stringify({ type, message, url: window.location.href }),
22 }).catch(() => {});
23 }
24
25 console.error = (...args: unknown[]) => {
26 report("console.error", args);
27 originalError.apply(console, args);
28 };
29
30 console.warn = (...args: unknown[]) => {
31 report("console.warn", args);
32 originalWarn.apply(console, args);
33 };
34
35 const onError = (e: ErrorEvent) => {
36 report("unhandled-error", [e.message, e.filename, e.lineno, e.colno]);
37 };
38
39 const onRejection = (e: PromiseRejectionEvent) => {
40 report("unhandled-rejection", [String(e.reason)]);
41 };
42
43 window.addEventListener("error", onError);
44 window.addEventListener("unhandledrejection", onRejection);
45
46 return () => {
47 console.error = originalError;
48 console.warn = originalWarn;
49 window.removeEventListener("error", onError);
50 window.removeEventListener("unhandledrejection", onRejection);
51 };
52 }, []);
53
54 return null;
55}
56