From 4e81a6a4106e4e125b0eefda042b75cfae0a5f23 Mon Sep 17 00:00:00 2001 From: Gar Date: Mon, 29 Jul 2024 09:40:53 -0700 Subject: [PATCH] fix: always set exit code if exiting uncleanly (#7674) An erroneous assumption was that if this was explicitly set, then the exit was still intentional. This is not the case. Closes: https://github.com/npm/cli/issues/7672 --------- Co-authored-by: Chris Sidi --- lib/cli/exit-handler.js | 5 +++-- test/lib/cli/exit-handler.js | 7 ++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/cli/exit-handler.js b/lib/cli/exit-handler.js index fff95165a18de..e76b08c80a635 100644 --- a/lib/cli/exit-handler.js +++ b/lib/cli/exit-handler.js @@ -66,8 +66,9 @@ class ExitHandler { } #handleProcessExit (code) { - // Force exit code to a number if it has not been set - const exitCode = typeof code === 'number' ? code : (this.#exited ? 0 : 1) + const numCode = Number(code) || 0 + // Always exit w/ a non-zero code if exit handler was not called + const exitCode = this.#exited ? numCode : (numCode || 1) this.#process.exitCode = exitCode if (this.#notLoadedOrExited) { diff --git a/test/lib/cli/exit-handler.js b/test/lib/cli/exit-handler.js index 90d130a399265..939c9617aff56 100644 --- a/test/lib/cli/exit-handler.js +++ b/test/lib/cli/exit-handler.js @@ -194,15 +194,16 @@ t.test('exit handler never called', async t => { const { logs, errors } = await mockExitHandler(t, { config: { loglevel: 'silent' }, }) - process.emit('exit', 1) + process.emit('exit', 0) t.strictSame(logs, []) t.strictSame(errors(), [''], 'one empty string') + t.equal(process.exitCode, 1) }) t.test('loglevel notice', async (t) => { const { logs, errors } = await mockExitHandler(t) - process.emit('exit', 1) - t.equal(process.exitCode, 1) + process.emit('exit', 2) + t.equal(process.exitCode, 2) t.match(logs.error, [ 'Exit handler never called!', /error with npm itself/,