web/app/components/dev-error-reporter.tsxblame
View source
9e346cc1"use client";
9e346cc2
9e346cc3import { useEffect } from "react";
9e346cc4
9e346cc5export function DevErrorReporter() {
9e346cc6 useEffect(() => {
9e346cc7 if (process.env.NODE_ENV === "production") return;
9e346cc8
9e346cc9 const originalError = console.error;
9e346cc10 const originalWarn = console.warn;
9e346cc11
9e346cc12 function report(type: string, args: unknown[]) {
9e346cc13 const message = args
9e346cc14 .map((a) => (typeof a === "string" ? a : JSON.stringify(a, null, 2)))
9e346cc15 .join(" ")
9e346cc16 .slice(0, 4000);
9e346cc17
9e346cc18 fetch("/api/dev-errors", {
9e346cc19 method: "POST",
9e346cc20 headers: { "Content-Type": "application/json" },
9e346cc21 body: JSON.stringify({ type, message, url: window.location.href }),
9e346cc22 }).catch(() => {});
9e346cc23 }
9e346cc24
9e346cc25 console.error = (...args: unknown[]) => {
9e346cc26 report("console.error", args);
9e346cc27 originalError.apply(console, args);
9e346cc28 };
9e346cc29
9e346cc30 console.warn = (...args: unknown[]) => {
9e346cc31 report("console.warn", args);
9e346cc32 originalWarn.apply(console, args);
9e346cc33 };
9e346cc34
9e346cc35 const onError = (e: ErrorEvent) => {
9e346cc36 report("unhandled-error", [e.message, e.filename, e.lineno, e.colno]);
9e346cc37 };
9e346cc38
9e346cc39 const onRejection = (e: PromiseRejectionEvent) => {
9e346cc40 report("unhandled-rejection", [String(e.reason)]);
9e346cc41 };
9e346cc42
9e346cc43 window.addEventListener("error", onError);
9e346cc44 window.addEventListener("unhandledrejection", onRejection);
9e346cc45
9e346cc46 return () => {
9e346cc47 console.error = originalError;
9e346cc48 console.warn = originalWarn;
9e346cc49 window.removeEventListener("error", onError);
9e346cc50 window.removeEventListener("unhandledrejection", onRejection);
9e346cc51 };
9e346cc52 }, []);
9e346cc53
9e346cc54 return null;
9e346cc55}