Log on unhandled errors and promise rejections

Test code:

    useEffect(() => {
        setTimeout(() => testFunctionSync(), 5000);
    }, []);

    useEffect(() => {
        testFunction();
    }, []);

    const testFunctionSync = () => {
        console.log("sleeping not");
        // sleep(2000);
        console.log("woke up not");
        throw new Error("Handle me");
    };

    const testFunction = async () => {
        console.log("sleeping");
        sleep(2000);
        console.log("woke up");
        throw new Error("Handle me");
    };

Refs:
- https://developer.mozilla.org/en-US/docs/Web/API/Window/unhandledrejection_event
- https://github.com/megahertz/electron-log/blob/master/src/renderer/lib/RendererErrorHandler.js
This commit is contained in:
Manav Rathi 2024-04-10 13:05:00 +05:30
parent af79f4f0c9
commit e0fe018f34
No known key found for this signature in database
2 changed files with 35 additions and 1 deletions

View file

@ -1,7 +1,10 @@
import { CustomHead } from "@/next/components/Head";
import { setupI18n } from "@/next/i18n";
import log from "@/next/log";
import { logStartupBanner } from "@/next/log-web";
import {
logStartupBanner,
logUnhandledErrorsAndRejections,
} from "@/next/log-web";
import { AppUpdateInfo } from "@/next/types/ipc";
import {
APPS,
@ -147,9 +150,13 @@ export default function App({ Component, pageProps }: AppProps) {
setupI18n().finally(() => setIsI18nReady(true));
const userId = (getData(LS_KEYS.USER) as User)?.id;
logStartupBanner(APPS.PHOTOS, userId);
logUnhandledErrorsAndRejections(true);
HTTPService.setHeaders({
"X-Client-Package": CLIENT_PACKAGE_NAMES.get(APPS.PHOTOS),
});
return () => {
logUnhandledErrorsAndRejections(false);
};
}, []);
useEffect(() => {

View file

@ -18,6 +18,33 @@ export const logStartupBanner = (appId: string, userId?: number) => {
log.info(`Starting ente-${appIdL}-web ${buildId}uid ${userId ?? 0}`);
};
/**
* Attach handlers to log any unhandled exceptions and promise rejections.
*
* @param attach If true, attach handlers, and if false, remove them. This
* allows us to use this in a React hook that cleans up after itself.
*/
export const logUnhandledErrorsAndRejections = (attach: boolean) => {
const handleError = (event: ErrorEvent) => {
log.error("Unhandled error", event.error);
};
const handleUnhandledRejection = (event: PromiseRejectionEvent) => {
log.error("Unhandled promise rejection", event.reason);
};
if (attach) {
window.addEventListener("error", handleError);
window.addEventListener("unhandledrejection", handleUnhandledRejection);
} else {
window.removeEventListener("error", handleError);
window.removeEventListener(
"unhandledrejection",
handleUnhandledRejection,
);
}
};
interface LogEntry {
timestamp: number;
logLine: string;