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 1f52aa4
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 2 deletions.
6 changes: 5 additions & 1 deletion index.d.ts
Expand Up @@ -9,7 +9,11 @@ export interface Options {
readonly concurrency?: number;

/**
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.
When `true`, the first mapper rejection will be rejected back to the consumer.
When `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.
Caveat: When `true`, 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](https://github.com/sindresorhus/p-map/issues/51) can be implemented for abort control.
@default true
*/
Expand Down
6 changes: 5 additions & 1 deletion readme.md
Expand Up @@ -72,7 +72,11 @@ Number of concurrently pending promises returned by `mapper`.
Type: `boolean`\
Default: `true`

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.
When `true`, the first mapper rejection will be rejected back to the consumer.

When `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.

Caveat: When `true`, 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](https://github.com/sindresorhus/p-map/issues/51) can be implemented for abort control.

### pMapSkip

Expand Down
32 changes: 32 additions & 0 deletions test.js
Expand Up @@ -378,3 +378,35 @@ 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 1f52aa4

Please sign in to comment.