Skip to content

Commit 675c210

Browse files
jasnelltargos
authored andcommitted
lib: add reason to AbortSignal
A new reason property was recently added to the AbortSignal spec. ```js const ac = new AbortController(); ac.abort(new Error('boom!')); console.loc(ac.signal.reason); // Error('boom!'); ``` Signed-off-by: James M Snell <[email protected]> PR-URL: #40807 Reviewed-By: Antoine du Hamel <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]> Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Minwoo Jung <[email protected]> Reviewed-By: Robert Nagy <[email protected]>
1 parent 62171eb commit 675c210

File tree

3 files changed

+73
-8
lines changed

3 files changed

+73
-8
lines changed

doc/api/globals.md

+30-2
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,21 @@ ac.abort();
4646
console.log(ac.signal.aborted); // Prints True
4747
```
4848

49-
### `abortController.abort()`
49+
### `abortController.abort([reason])`
5050

5151
<!-- YAML
5252
added:
5353
- v15.0.0
5454
- v14.17.0
55+
changes:
56+
- version: REPLACEME
57+
pr-url: https://github.com/nodejs/node/pull/40807
58+
description: Added the new optional reason argument.
5559
-->
5660

61+
* `reason` {any} An optional reason, retrievable on the `AbortSignal`s
62+
`reason` property.
63+
5764
Triggers the abort signal, causing the `abortController.signal` to emit
5865
the `'abort'` event.
5966

@@ -80,14 +87,19 @@ added:
8087
The `AbortSignal` is used to notify observers when the
8188
`abortController.abort()` method is called.
8289

83-
#### Static method: `AbortSignal.abort()`
90+
#### Static method: `AbortSignal.abort([reason])`
8491

8592
<!-- YAML
8693
added:
8794
- v15.12.0
8895
- v14.17.0
96+
changes:
97+
- version: REPLACEME
98+
pr-url: https://github.com/nodejs/node/pull/40807
99+
description: Added the new optional reason argument.
89100
-->
90101

102+
* `reason`: {any}
91103
* Returns: {AbortSignal}
92104

93105
Returns a new already aborted `AbortSignal`.
@@ -152,6 +164,22 @@ added:
152164
An optional callback function that may be set by user code to be notified
153165
when the `abortController.abort()` function has been called.
154166

167+
#### `abortSignal.reason`
168+
169+
<!-- YAML
170+
added: REPLACEME
171+
-->
172+
173+
* Type: {any}
174+
175+
An optional reason specified when the `AbortSignal` was triggered.
176+
177+
```js
178+
const ac = new AbortController();
179+
ac.abort(new Error('boom!'));
180+
console.log(ac.signal.reason); // Error('boom!');
181+
```
182+
155183
## Class: `Buffer`
156184

157185
<!-- YAML

lib/internal/abort_controller.js

+30-6
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ const {
3030
} = require('internal/errors');
3131

3232
const kAborted = Symbol('kAborted');
33+
const kReason = Symbol('kReason');
3334

3435
function customInspect(self, obj, depth, options) {
3536
if (depth < 0)
@@ -52,19 +53,34 @@ class AbortSignal extends EventTarget {
5253
throw new ERR_ILLEGAL_CONSTRUCTOR();
5354
}
5455

56+
/**
57+
* @type {boolean}
58+
*/
5559
get aborted() {
5660
validateAbortSignal(this);
5761
return !!this[kAborted];
5862
}
5963

64+
/**
65+
* @type {any}
66+
*/
67+
get reason() {
68+
validateAbortSignal(this);
69+
return this[kReason];
70+
}
71+
6072
[customInspectSymbol](depth, options) {
6173
return customInspect(this, {
6274
aborted: this.aborted
6375
}, depth, options);
6476
}
6577

66-
static abort() {
67-
return createAbortSignal(true);
78+
/**
79+
* @param {any} reason
80+
* @returns {AbortSignal}
81+
*/
82+
static abort(reason) {
83+
return createAbortSignal(true, reason);
6884
}
6985
}
7086

@@ -81,16 +97,18 @@ ObjectDefineProperty(AbortSignal.prototype, SymbolToStringTag, {
8197

8298
defineEventHandler(AbortSignal.prototype, 'abort');
8399

84-
function createAbortSignal(aborted = false) {
100+
function createAbortSignal(aborted = false, reason = undefined) {
85101
const signal = new EventTarget();
86102
ObjectSetPrototypeOf(signal, AbortSignal.prototype);
87103
signal[kAborted] = aborted;
104+
signal[kReason] = reason;
88105
return signal;
89106
}
90107

91-
function abortSignal(signal) {
108+
function abortSignal(signal, reason) {
92109
if (signal[kAborted]) return;
93110
signal[kAborted] = true;
111+
signal[kReason] = reason;
94112
const event = new Event('abort', {
95113
[kTrustEvent]: true
96114
});
@@ -112,14 +130,20 @@ class AbortController {
112130
this[kSignal] = createAbortSignal();
113131
}
114132

133+
/**
134+
* @type {AbortSignal}
135+
*/
115136
get signal() {
116137
validateAbortController(this);
117138
return this[kSignal];
118139
}
119140

120-
abort() {
141+
/**
142+
* @param {any} reason
143+
*/
144+
abort(reason) {
121145
validateAbortController(this);
122-
abortSignal(this[kSignal]);
146+
abortSignal(this[kSignal], reason);
123147
}
124148

125149
[customInspectSymbol](depth, options) {

test/parallel/test-abortcontroller.js

+13
Original file line numberDiff line numberDiff line change
@@ -140,3 +140,16 @@ const { ok, strictEqual, throws } = require('assert');
140140
strictEqual(inspect(ac, { depth: null }),
141141
'AbortController { signal: AbortSignal { aborted: false } }');
142142
}
143+
144+
{
145+
// Test AbortSignal.reason
146+
const ac = new AbortController();
147+
ac.abort('reason');
148+
strictEqual(ac.signal.reason, 'reason');
149+
}
150+
151+
{
152+
// Test AbortSignal.reason
153+
const signal = AbortSignal.abort('reason');
154+
strictEqual(signal.reason, 'reason');
155+
}

0 commit comments

Comments
 (0)