From 63816160d2014c1cf77faaceb51d45e45057cc78 Mon Sep 17 00:00:00 2001 From: Boopathi Rajaa Date: Fri, 21 Oct 2022 19:38:05 +0200 Subject: [PATCH] fix: propagate batchFn sync throws to the loader instead of crashing --- src/__tests__/abuse.test.js | 20 ++++++++++++++++++++ src/index.js | 11 ++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/__tests__/abuse.test.js b/src/__tests__/abuse.test.js index 9300e80..b9eb934 100644 --- a/src/__tests__/abuse.test.js +++ b/src/__tests__/abuse.test.js @@ -97,6 +97,26 @@ describe('Provides descriptive error messages for API abuse', () => { ); }); + it('Batch function must return a Promise, not error synchronously', async () => { + // $FlowExpectError + const badLoader = new DataLoader(() => { + throw new Error("Mock Synchronous Error") + }); + + let caughtError; + try { + await badLoader.load(1); + } catch (error) { + caughtError = error; + } + expect(caughtError).toBeInstanceOf(Error); + expect((caughtError: any).message).toBe( + 'DataLoader must be constructed with a function which accepts ' + + 'Array and returns Promise>, but the function ' + + `errored synchronously: Error: Mock Synchronous Error.` + ); + }); + it('Batch function must return a Promise, not a value', async () => { // Note: this is returning the keys directly, rather than a promise to keys. // $FlowExpectError diff --git a/src/index.js b/src/index.js index 87dade9..bcdec7d 100644 --- a/src/index.js +++ b/src/index.js @@ -304,7 +304,16 @@ function dispatchBatch( // Call the provided batchLoadFn for this loader with the batch's keys and // with the loader as the `this` context. - var batchPromise = loader._batchLoadFn(batch.keys); + var batchPromise; + try { + batchPromise = loader._batchLoadFn(batch.keys); + } catch (e) { + return failedDispatch(loader, batch, new TypeError( + 'DataLoader must be constructed with a function which accepts ' + + 'Array and returns Promise>, but the function ' + + `errored synchronously: ${String(e)}.` + )); + } // Assert the expected response from batchLoadFn if (!batchPromise || typeof batchPromise.then !== 'function') {