Skip to content

Commit e08df49

Browse files
jasnelldanielleadams
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 28a216a commit e08df49

File tree

3 files changed

+79
-10
lines changed

3 files changed

+79
-10
lines changed

doc/api/globals.md

+36-4
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,21 @@ ac.abort();
4444
console.log(ac.signal.aborted); // Prints True
4545
```
4646

47-
### `abortController.abort()`
47+
### `abortController.abort([reason])`
4848

4949
<!-- YAML
50-
added: v15.0.0
50+
added:
51+
- v15.0.0
52+
- v14.17.0
53+
changes:
54+
- version: REPLACEME
55+
pr-url: https://github.com/nodejs/node/pull/40807
56+
description: Added the new optional reason argument.
5157
-->
5258

59+
* `reason` {any} An optional reason, retrievable on the `AbortSignal`s
60+
`reason` property.
61+
5362
Triggers the abort signal, causing the `abortController.signal` to emit
5463
the `'abort'` event.
5564

@@ -72,12 +81,19 @@ added: v15.0.0
7281
The `AbortSignal` is used to notify observers when the
7382
`abortController.abort()` method is called.
7483

75-
#### Static method: `AbortSignal.abort()`
84+
#### Static method: `AbortSignal.abort([reason])`
7685

7786
<!-- YAML
78-
added: v15.12.0
87+
added:
88+
- v15.12.0
89+
- v14.17.0
90+
changes:
91+
- version: REPLACEME
92+
pr-url: https://github.com/nodejs/node/pull/40807
93+
description: Added the new optional reason argument.
7994
-->
8095

96+
* `reason`: {any}
8197
* Returns: {AbortSignal}
8298

8399
Returns a new already aborted `AbortSignal`.
@@ -136,6 +152,22 @@ added: v15.0.0
136152
An optional callback function that may be set by user code to be notified
137153
when the `abortController.abort()` function has been called.
138154

155+
#### `abortSignal.reason`
156+
157+
<!-- YAML
158+
added: REPLACEME
159+
-->
160+
161+
* Type: {any}
162+
163+
An optional reason specified when the `AbortSignal` was triggered.
164+
165+
```js
166+
const ac = new AbortController();
167+
ac.abort(new Error('boom!'));
168+
console.log(ac.signal.reason); // Error('boom!');
169+
```
170+
139171
## Class: `Buffer`
140172

141173
<!-- 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)