From 8cce2205a39e4c21809201a78baf2e109179f230 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 20 Mar 2023 10:42:28 +0100 Subject: [PATCH] backend-app-api: register global error handlers Signed-off-by: Patrik Oldsberg --- .changeset/rotten-carrots-cheer.md | 5 +++++ .../src/wiring/BackendInitializer.ts | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 .changeset/rotten-carrots-cheer.md diff --git a/.changeset/rotten-carrots-cheer.md b/.changeset/rotten-carrots-cheer.md new file mode 100644 index 0000000000..58da6d2a21 --- /dev/null +++ b/.changeset/rotten-carrots-cheer.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-app-api': patch +--- + +Register unhandled rejection and uncaught exception handlers to avoid backend crashes. diff --git a/packages/backend-app-api/src/wiring/BackendInitializer.ts b/packages/backend-app-api/src/wiring/BackendInitializer.ts index 2a8fa1e720..b2c62c2122 100644 --- a/packages/backend-app-api/src/wiring/BackendInitializer.ts +++ b/packages/backend-app-api/src/wiring/BackendInitializer.ts @@ -165,6 +165,25 @@ export class BackendInitializer { ); await registerInit.init.func(deps); } + + // Once the backend is started, any uncaught errors or unhandled rejections are caught + // and logged, in order to avoid crashing the entire backend on local failures. + if (process.env.NODE_ENV !== 'test') { + const rootLogger = await this.#serviceHolder.get( + coreServices.rootLogger, + 'root', + ); + process.on('unhandledRejection', (reason: Error) => { + rootLogger + ?.child({ type: 'unhandledRejection' }) + ?.error('Unhandled rejection', reason); + }); + process.on('uncaughtException', error => { + rootLogger + ?.child({ type: 'uncaughtException' }) + ?.error('Uncaught exception', error); + }); + } } #resolveInitOrder(registerInits: Array) {