Skip to content

Commit d321773

Browse files
committed
1 parent c5c99eb commit d321773

11 files changed

Lines changed: 126 additions & 39 deletions

.dictionary.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ gpgsign
1414
graphqlrc
1515
hmarr
1616
iife
17+
instanceof
1718
keyid
1819
larsgw
1920
lcov

.markdownlint.jsonc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@
8484
"div",
8585
"figcaption",
8686
"figure",
87+
"h4",
8788
"img",
8889
"script",
8990
"small",

README.md

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ This package is an ECMAScript Proposal spec-compliant [ponyfill][2] for [`Aggreg
2727

2828
## When should I use this?
2929

30-
Use this package when you want to throw `AggregateError` objects in unsupported ECMAScript environments (`< es2021`).
30+
Use this package when you want to throw `AggregateError` objects in unsupported environments (`< es2021`).
3131

3232
## Install
3333

@@ -56,20 +56,40 @@ import AggregateError from '@flex-development/aggregate-error-ponyfill'
5656
try {
5757
throw new AggregateError([new Error('some error')], 'oh no!')
5858
} catch (e) {
59-
console.error(e.message) // 'oh no!'
60-
console.error(e.name) // 'AggregateError'
61-
console.error(e.errors) // [Error: 'some error']
59+
console.debug(e instanceof AggregateError) // true
60+
console.error(e.name) // 'AggregateError'
61+
console.error(e.message) // 'oh no!'
62+
console.error(e.errors) // [Error: 'some error']
6263
}
6364
```
6465

6566
## API
6667

6768
This package exports no identifiers. The default export is `AggregateError`.
6869

69-
### `new AggregateError<T>(errors: Iterable<T>, message?: string)`
70+
### <h4>`new AggregateError<T, C>(errors: Iterable<T>, message?: string, options?: Options<C>)`</h4>
7071

7172
Wrap several errors in a single error so that multiple errors can be reported by an operation.
7273

74+
#### `errors`
75+
76+
An iterable of errors.
77+
78+
#### `message`
79+
80+
An optional human-readable description of the aggregate error.
81+
82+
#### `options`
83+
84+
An object that has the following properties:
85+
86+
##### `cause`
87+
88+
The specific cause of the aggregate error.
89+
90+
When catching and re-throwing an error with a more-specific or useful error message, this property can be used to pass
91+
the original error.
92+
7393
## Types
7494

7595
This package is fully typed with [TypeScript][3].

src/__tests__/ponyfill.spec.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,17 @@ import TestSubject from '../ponyfill'
88
describe('unit:ponyfill', () => {
99
it('should create spec-compliant AggregateError', () => {
1010
// Arrange
11-
const errors = [new SyntaxError(faker.lorem.sentence()), { code: 400 }]
12-
const message = faker.lorem.sentence()
11+
const cause = new Error('The server responded with a 500 status')
12+
const symptom = new Error('The message failed to send')
13+
const errors = [symptom, cause]
1314

1415
// Act
15-
const result = new TestSubject(errors, message)
16+
const result = new TestSubject(errors, symptom.message, { cause })
1617

1718
// Expect
1819
expect(result).to.be.an.instanceof(Error)
1920
expect(result.errors).to.deep.equal(errors)
20-
expect(result.message).to.equal(message)
21+
expect(result.message).to.equal(symptom.message)
2122
expect(result.name).to.equal('AggregateError')
2223
})
2324

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@
33
* @module aggregate-error-ponyfill
44
*/
55

6+
export type { default as Options } from './options'
67
export { default } from './ponyfill'

src/options-get-iterator-method.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/**
2+
* @file AggregateError - GetIteratorMethodOptions
3+
* @module aggregate-error-ponyfill/ponyfill/GetIteratorMethodOptions
4+
*/
5+
6+
import type getIteratorMethod from 'es-abstract/helpers/getIteratorMethod'
7+
8+
/**
9+
* Iterator method creation options type.
10+
*
11+
* @internal
12+
*
13+
* @see {@linkcode getIteratorMethod}
14+
*/
15+
type GetIteratorMethodOptions = Parameters<typeof getIteratorMethod>['0']
16+
17+
export type { GetIteratorMethodOptions as default }

src/options.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/**
2+
* @file AggregateError - Options
3+
* @module aggregate-error-ponyfill/ponyfill/Options
4+
*/
5+
6+
/**
7+
* `AggregateError` options.
8+
*
9+
* @see https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/AggregateError/AggregateError#parameters
10+
*
11+
* @template Cause - Error cause type
12+
*/
13+
interface Options<Cause = unknown> {
14+
/**
15+
* The specific cause of the error.
16+
*
17+
* When catching and re-throwing an error with a more-specific or useful error
18+
* message, this property can be used to pass the original error.
19+
*
20+
* @see https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Error/cause
21+
*/
22+
cause?: Cause
23+
}
24+
25+
export type { Options as default }

src/ponyfill.ts

Lines changed: 39 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,64 +4,77 @@
44
*/
55

66
import AdvanceStringIndex from 'es-abstract/2021/AdvanceStringIndex'
7+
import CreateProperty from 'es-abstract/2021/CreateDataProperty'
78
import CreatePropertyOrThrow from 'es-abstract/2021/CreateDataPropertyOrThrow'
89
import GetMethod from 'es-abstract/2021/GetMethod'
910
import IsArray from 'es-abstract/2021/IsArray'
1011
import IterableToList from 'es-abstract/2021/IterableToList'
1112
import Type from 'es-abstract/2021/Type'
1213
import getIteratorMethod from 'es-abstract/helpers/getIteratorMethod'
14+
import type Options from './options'
15+
import type GetIteratorMethodOptions from './options-get-iterator-method'
1316

1417
/**
15-
* Iterator method options type.
18+
* The `AggregateError` object represents an error when several errors need to
19+
* be wrapped in a single error.
1620
*
17-
* @see {@link getIteratorMethod}
18-
*/
19-
type GetIteratorMethodOptions = Parameters<typeof getIteratorMethod>['0']
20-
21-
/**
22-
* A single error that represents a group of errors.
23-
*
24-
* It is thrown when multiple errors need to be reported by an operation, e.g.
25-
* by [`Promise.any()`][1] when all promises passed to it reject.
21+
* It is thrown when multiple errors need to be reported by an operation, for
22+
* example by [`Promise.any()`][1] when all promises passed to it reject.
2623
*
2724
* [1]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise/any
2825
*
29-
* @see https://tc39.es/proposal-promise-any#sec-aggregate-error-objects
26+
* @see https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/AggregateError
3027
*
3128
* @template T - Aggregated error type
29+
* @template C - Error cause type
3230
*
31+
* @class
3332
* @extends {Error}
3433
*/
35-
class AggregateError<T = any> extends Error {
34+
class AggregateError<T = any, C = unknown> extends Error {
35+
/**
36+
* Error cause.
37+
*
38+
* @see https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Error/cause
39+
*
40+
* @public
41+
* @member {C | undefined} cause
42+
*/
43+
public cause?: C
44+
3645
/**
3746
* @public
38-
* @member {T[]} errors - Aggregated errors
47+
* @member {T[]} errors - Array containing aggregated errors
3948
*/
40-
public errors: T[]
49+
public errors: T[] = []
4150

4251
/**
4352
* @public
4453
* @override
4554
* @readonly
46-
* @member {'AggregateError'} name - Error subclass name
55+
* @member {string} name - Error name
4756
*/
48-
public override readonly name: 'AggregateError' = 'AggregateError'
57+
public override readonly name: string = 'AggregateError'
4958

5059
/**
51-
* Creates a single error representing `errors`.
60+
* Creates an error for several errors that need to be wrapped in a single
61+
* error.
5262
*
5363
* @example
5464
* new AggregateError([new Error('some error')])
65+
* @example
5566
* new AggregateError([new Error('err1'), new Error('err2')], 'oh no!')
5667
*
57-
* @param {Iterable<T>} errors - Aggregated errors
58-
* @param {string} [message] - Human-readable error message
68+
* @param {Iterable<T>} errors - An iterable of errors
69+
* @param {string} [message] - Human-readable description of the error
70+
* @param {Options<C>} [options] - Error options
71+
* @param {C} [options.cause] - The original cause of the error
5972
*/
60-
constructor(errors: Iterable<T>, message?: string) {
73+
constructor(errors: Iterable<T>, message?: string, options?: Options<C>) {
6174
super(message)
6275

6376
/**
64-
* Iterator method options.
77+
* Iterator method creation options.
6578
*
6679
* @const {GetIteratorMethodOptions} es
6780
*/
@@ -73,17 +86,14 @@ class AggregateError<T = any> extends Error {
7386
}
7487

7588
/**
76-
* Function that returns an iterator.
89+
* Array containing aggregated errors.
7790
*
78-
* @const {() => Iterator<T>} method
91+
* @const {T[]} arr
7992
*/
80-
const method: () => Iterator<T> = getIteratorMethod(es, errors)
81-
82-
// create aggregated error list
83-
this.errors = IterableToList(errors, method)
93+
const arr: T[] = IterableToList(errors, getIteratorMethod(es, errors))
8494

85-
// re-assign errors property or throw if errors isn't iterable
86-
CreatePropertyOrThrow(this, 'errors', IterableToList(this.errors, method))
95+
CreatePropertyOrThrow(this, 'errors', arr)
96+
CreateProperty(this, 'cause', options?.cause)
8797
}
8898
}
8999

tsconfig.build.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"extends": "./tsconfig.json",
99
"files": [
1010
"./typings/es-abstract/2021/AdvanceStringIndex.d.ts",
11+
"./typings/es-abstract/2021/CreateDataProperty.d.ts",
1112
"./typings/es-abstract/2021/CreateDataPropertyOrThrow.d.ts",
1213
"./typings/es-abstract/2021/GetMethod.d.ts",
1314
"./typings/es-abstract/2021/IsArray.d.ts",
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
declare module 'es-abstract/2021/CreateDataProperty' {
2+
const CreateDataProperty: typeof import('es-abstract/2019/CreateDataProperty')
3+
export default CreateDataProperty
4+
}

0 commit comments

Comments
 (0)