From 19ec98c5dd3f6edca0ae848893d19edd74e9cae8 Mon Sep 17 00:00:00 2001 From: Eelco Lempsink Date: Sat, 2 Feb 2019 19:46:19 +0100 Subject: [PATCH] =?UTF-8?q?Don=E2=80=99t=20call=20`release`=20with=20an=20?= =?UTF-8?q?exit=20code=20(#6981)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Don’t call `release` with an exit code The `release` signature is incorrect, because its first argument is a callback function that will be called when the release is done. By attaching it to the `run()` promise however, release will be called with the exit code as argument. When the exit code is `1`, the code will crash. This is very rare, but we’re seeing this when calling yarn from another node process (and possibly killing it too soon): ``` /node_modules/yarn/lib/cli.js:78119 callback(); ^ TypeError: callback is not a function at options.fs.rmdir (/node_modules/yarn/lib/cli.js:78119:9) at FSReqWrap.oncomplete (fs.js:141:20) ``` * Only resolve after releasing is done, improve type of `release`. Note that this slightly violates the type of runEventuallyWithFile, as the Promised resolved by the release callback might return an Error object. But since this error was also not handled before, it’s out of scope for the fix of this patch. --- src/cli/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cli/index.js b/src/cli/index.js index a4b307d57a..d0c58f1c6b 100644 --- a/src/cli/index.js +++ b/src/cli/index.js @@ -291,7 +291,7 @@ export async function main({ const runEventuallyWithFile = (mutexFilename: ?string, isFirstTime?: boolean): Promise => { return new Promise(resolve => { const lockFilename = mutexFilename || path.join(config.cwd, constants.SINGLE_INSTANCE_FILENAME); - lockfile.lock(lockFilename, {realpath: false}, (err: mixed, release: () => void) => { + lockfile.lock(lockFilename, {realpath: false}, (err: mixed, release: (() => void) => void) => { if (err) { if (isFirstTime) { reporter.warn(reporter.lang('waitingInstance')); @@ -303,7 +303,7 @@ export async function main({ onDeath(() => { process.exitCode = 1; }); - resolve(run().then(release)); + resolve(run().then(() => new Promise(resolve => release(resolve)))); } }); });