Skip to content

Commit

Permalink
Add test cases for multiple mapper errors with stop on error (#49)
Browse files Browse the repository at this point in the history
Co-authored-by: Sindre Sorhus <sindresorhus@gmail.com>
  • Loading branch information
huntharo and sindresorhus committed Oct 3, 2021
1 parent a24e909 commit af84dee
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 0 deletions.
2 changes: 2 additions & 0 deletions index.d.ts
Expand Up @@ -9,6 +9,8 @@ export interface Options {
readonly concurrency?: number;

/**
When set to `true`, the first mapper rejection will be rejected back to the consumer. Caveat: any already-started async mappers will continue to run until they resolve or reject. In the case of infinite concurrency with sync iterables *all* mappers are invoked on startup and will continue after the first rejection. [Issue #51](issues/51) can be implemented for abort control.
When set to `false`, instead of stopping when a promise rejects, it will wait for all the promises to settle and then reject with an [aggregated error](https://github.com/sindresorhus/aggregate-error) containing all the errors from the rejected promises.
@default true
Expand Down
2 changes: 2 additions & 0 deletions readme.md
Expand Up @@ -72,6 +72,8 @@ Number of concurrently pending promises returned by `mapper`.
Type: `boolean`\
Default: `true`

When set to `true`, the first mapper rejection will be rejected back to the consumer. Caveat: any already-started async mappers will continue to run until they resolve or reject. In the case of infinite concurrency with sync iterables *all* mappers are invoked on startup and will continue after the first rejection. [Issue #51](issues/51) can be implemented for abort control.

When set to `false`, instead of stopping when a promise rejects, it will wait for all the promises to settle and then reject with an [aggregated error](https://github.com/sindresorhus/aggregate-error) containing all the errors from the rejected promises.

### pMapSkip
Expand Down
31 changes: 31 additions & 0 deletions test.js
Expand Up @@ -378,3 +378,34 @@ test('incorrect input type', async t => {
await t.throwsAsync(task, {message: 'Expected `input` to be either an `Iterable` or `AsyncIterable`, got (number)'});
t.false(mapperCalled);
});
test('no unhandled rejected promises from mapper throws - infinite concurrency', async t => {
const input = [1, 2, 3];
const mappedValues = [];
await t.throwsAsync(
pMap(input, async value => {
mappedValues.push(value);
await delay(100);
throw new Error(`Oops! ${value}`);
}),
{message: 'Oops! 1'}
);
// Note: All 3 mappers get invoked, all 3 throw, even with `{stopOnError: true}` this
// should raise an AggregateError with all 3 exceptions instead of throwing 1
// exception and hiding the other 2.
t.deepEqual(mappedValues, [1, 2, 3]);
});

test('no unhandled rejected promises from mapper throws - concurrency 1', async t => {
const input = [1, 2, 3];
const mappedValues = [];
await t.throwsAsync(
pMap(input, async value => {
mappedValues.push(value);
await delay(100);
throw new Error(`Oops! ${value}`);
},
{concurrency: 1}),
{message: 'Oops! 1'}
);
t.deepEqual(mappedValues, [1]);
});

0 comments on commit af84dee

Please sign in to comment.