From c65e7584088cb3e8adb4a97977b11373e8275f6f Mon Sep 17 00:00:00 2001 From: Brian Botha Date: Fri, 16 Sep 2022 14:08:43 +1000 Subject: [PATCH] feat: added handler to detect promise deadlocks to `ExitHandlers.ts` #307 --- src/bin/errors.ts | 7 +++++++ src/bin/utils/ExitHandlers.ts | 16 ++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/src/bin/errors.ts b/src/bin/errors.ts index be6876a65..576fa21a6 100644 --- a/src/bin/errors.ts +++ b/src/bin/errors.ts @@ -49,6 +49,12 @@ class ErrorCLIPolykeyAgentProcess extends ErrorCLI { exitCode = sysexits.OSERR; } +class ErrorCLIPolykeyAsynchronousDeadlock extends ErrorCLI { + static description = + 'PolykeyAgent process exited unexpectedly, likely due to promise deadlock'; + exitCode = sysexits.SOFTWARE; +} + class ErrorNodeFindFailed extends ErrorCLI { static description = 'Failed to find the node in the DHT'; exitCode = 1; @@ -70,6 +76,7 @@ export { ErrorCLIFileRead, ErrorCLIPolykeyAgentStatus, ErrorCLIPolykeyAgentProcess, + ErrorCLIPolykeyAsynchronousDeadlock, ErrorNodeFindFailed, ErrorNodePingFailed, }; diff --git a/src/bin/utils/ExitHandlers.ts b/src/bin/utils/ExitHandlers.ts index 2fdd74f03..24fa27871 100644 --- a/src/bin/utils/ExitHandlers.ts +++ b/src/bin/utils/ExitHandlers.ts @@ -1,6 +1,7 @@ import process from 'process'; import * as binUtils from './utils'; import ErrorPolykey from '../../ErrorPolykey'; +import * as CLIErrors from '../errors'; class ExitHandlers { /** @@ -84,6 +85,19 @@ class ExitHandlers { } }; + protected deadlockHandler = async () => { + if (process.exitCode == null) { + const e = new CLIErrors.ErrorCLIPolykeyAsynchronousDeadlock(); + process.stderr.write( + binUtils.outputFormatter({ + type: this._errFormat, + data: e, + }), + ); + process.exitCode = e.exitCode; + } + }; + /** * Automatically installs all handlers */ @@ -110,6 +124,7 @@ class ExitHandlers { // Both synchronous and asynchronous errors are handled process.once('unhandledRejection', this.errorHandler); process.once('uncaughtException', this.errorHandler); + process.once('beforeExit', this.deadlockHandler); } public uninstall() { @@ -119,6 +134,7 @@ class ExitHandlers { process.removeListener('SIGHUP', this.signalHandler); process.removeListener('unhandledRejection', this.errorHandler); process.removeListener('uncaughtException', this.errorHandler); + process.removeListener('beforeExit', this.deadlockHandler); } /**