From 6db755dabc32d81eceeb3152413bb70298a5c710 Mon Sep 17 00:00:00 2001 From: Hiroki Osame Date: Fri, 14 May 2021 17:48:03 -0400 Subject: [PATCH] fix: prevent callback from triggering twice when callback throws closes #542 --- src/__tests__/volume/callback-error.test.ts | 15 +++++++++++++++ src/volume.ts | 5 ++++- 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 src/__tests__/volume/callback-error.test.ts diff --git a/src/__tests__/volume/callback-error.test.ts b/src/__tests__/volume/callback-error.test.ts new file mode 100644 index 000000000..a2b56a7e9 --- /dev/null +++ b/src/__tests__/volume/callback-error.test.ts @@ -0,0 +1,15 @@ +jest.useFakeTimers('modern'); + +// Fixes https://github.com/streamich/memfs/issues/542 +it('should throw error instead of callback', () => { + const { Volume } = require('../../volume'); + const vol = new Volume(); + + vol.writeFile('/asdf.txt', 'asdf', 'utf8', (err) => { + if (!err) { + throw new Error('try to trigger catch'); + } + }); + + expect(() => jest.runAllTimers()).toThrow('try to trigger catch'); +}); diff --git a/src/volume.ts b/src/volume.ts index 565118b17..7193074e9 100644 --- a/src/volume.ts +++ b/src/volume.ts @@ -826,11 +826,14 @@ export class Volume { private wrapAsync(method: (...args) => void, args: any[], callback: TCallback) { validateCallback(callback); setImmediate(() => { + let result; try { - callback(null, method.apply(this, args)); + result = method.apply(this, args); } catch (err) { callback(err); + return; } + callback(null, result); }); }