@@ -2,6 +2,7 @@ import { expect } from 'chai';
22import { describe , it } from 'mocha' ;
33
44import { expectPromise } from '../../__testUtils__/expectPromise.js' ;
5+ import { resolveOnNextTick } from '../../__testUtils__/resolveOnNextTick.js' ;
56
67import { mapAsyncIterable } from '../mapAsyncIterable.js' ;
78
@@ -248,6 +249,66 @@ describe('mapAsyncIterable', () => {
248249 } ) ;
249250 } ) ;
250251
252+ it ( 'waits for source handlers before actually throwing' , async ( ) => {
253+ const abortReason = new Error ( 'aborted' ) ;
254+ let storedReason : unknown ;
255+
256+ const iterable : AsyncIterableIterator < number > = {
257+ [ Symbol . asyncIterator ] ( ) {
258+ return this ;
259+ } ,
260+ next ( ) {
261+ return Promise . resolve ( { value : 1 , done : false } ) ;
262+ } ,
263+ async throw ( reason ?: unknown ) {
264+ if ( storedReason === undefined ) {
265+ await resolveOnNextTick ( ) ;
266+ // eslint-disable-next-line require-atomic-updates
267+ storedReason = reason ;
268+ return { value : undefined , done : true } ;
269+ }
270+ // eslint-disable-next-line @typescript-eslint/only-throw-error
271+ throw storedReason ;
272+ } ,
273+ return ( ) {
274+ return Promise . resolve ( { value : undefined , done : true } ) ;
275+ } ,
276+ } ;
277+
278+ const mapped = mapAsyncIterable ( iterable , ( x ) => x ) ;
279+
280+ expect ( await mapped . next ( ) ) . to . deep . equal ( { value : 1 , done : false } ) ;
281+
282+ const thrown = mapped . throw ( abortReason ) ;
283+ await expectPromise ( thrown ) . toRejectWith ( 'aborted' ) ;
284+ expect ( storedReason ) . to . equal ( abortReason ) ;
285+ } ) ;
286+
287+ it ( 'throws given reason, ignoring source throw result' , async ( ) => {
288+ const iterable : AsyncIterableIterator < number > = {
289+ [ Symbol . asyncIterator ] ( ) {
290+ return this ;
291+ } ,
292+ next ( ) {
293+ return Promise . resolve ( { value : 1 , done : false } ) ;
294+ } ,
295+ throw ( _reason ?: unknown ) {
296+ return Promise . resolve ( { value : 1 , done : false } ) ;
297+ } ,
298+ return ( ) {
299+ return Promise . resolve ( { value : undefined , done : true } ) ;
300+ } ,
301+ } ;
302+
303+ const mapped = mapAsyncIterable ( iterable , ( x ) => x ) ;
304+
305+ expect ( await mapped . next ( ) ) . to . deep . equal ( { value : 1 , done : false } ) ;
306+
307+ const abortReason = new Error ( 'aborted' ) ;
308+ const thrown = mapped . throw ( abortReason ) ;
309+ await expectPromise ( thrown ) . toRejectWith ( 'aborted' ) ;
310+ } ) ;
311+
251312 it ( 'passes through caught errors through async generators' , async ( ) => {
252313 async function * source ( ) {
253314 yield 1 ;
0 commit comments