From 6c53a274f50ea7965e92fe314e95cef6bd57c440 Mon Sep 17 00:00:00 2001 From: Ivan Goncharov Date: Fri, 2 Apr 2021 17:33:21 +0300 Subject: [PATCH] mapAsyncIterator: allow 'rejectCallback' to only be synchronous (#3012) --- .../__tests__/mapAsyncIterator-test.js | 22 +++++++------------ src/subscription/mapAsyncIterator.js | 11 +++++----- 2 files changed, 14 insertions(+), 19 deletions(-) diff --git a/src/subscription/__tests__/mapAsyncIterator-test.js b/src/subscription/__tests__/mapAsyncIterator-test.js index 3db45226ae..80f6e45a94 100644 --- a/src/subscription/__tests__/mapAsyncIterator-test.js +++ b/src/subscription/__tests__/mapAsyncIterator-test.js @@ -354,13 +354,19 @@ describe('mapAsyncIterator', () => { ); }); - async function testClosesSourceWithRejectMapper(mapper: (Error) => T) { + it('closes source if mapper throws an error', async () => { async function* source() { yield 1; throw new Error(2); } - const throwOver1 = mapAsyncIterator(source(), (x) => x, mapper); + const throwOver1 = mapAsyncIterator( + source(), + (x) => x, + (error) => { + throw new Error('Cannot count to ' + error.message); + }, + ); expect(await throwOver1.next()).to.deep.equal({ value: 1, done: false }); @@ -379,17 +385,5 @@ describe('mapAsyncIterator', () => { value: undefined, done: true, }); - } - - it('closes source if mapper throws an error', async () => { - await testClosesSourceWithRejectMapper((error) => { - throw new Error('Cannot count to ' + error.message); - }); - }); - - it('closes source if mapper rejects', async () => { - await testClosesSourceWithRejectMapper((error) => - Promise.reject(new Error('Cannot count to ' + error.message)), - ); }); }); diff --git a/src/subscription/mapAsyncIterator.js b/src/subscription/mapAsyncIterator.js index eef86d9ab2..0197322b4f 100644 --- a/src/subscription/mapAsyncIterator.js +++ b/src/subscription/mapAsyncIterator.js @@ -7,7 +7,7 @@ import type { PromiseOrValue } from '../jsutils/PromiseOrValue'; export function mapAsyncIterator( iterable: AsyncIterable | AsyncGenerator, callback: (T) => PromiseOrValue, - rejectCallback: (any) => PromiseOrValue = (error) => { + rejectCallback: (any) => U = (error) => { throw error; }, ): AsyncGenerator { @@ -31,10 +31,11 @@ export function mapAsyncIterator( } function mapReject(error: mixed) { - return asyncMapValue(error, rejectCallback).then( - iteratorResult, - abruptClose, - ); + try { + return { value: rejectCallback(error), done: false }; + } catch (callbackError) { + return abruptClose(callbackError); + } } /* TODO: Flow doesn't support symbols as keys: