summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorMatteo Collina <hello@matteocollina.com>2019-05-19 13:55:18 +0200
committerMatteo Collina <hello@matteocollina.com>2019-12-03 12:14:46 +0100
commitae8f20ec5eee55f648823392c9c4e9491c958b60 (patch)
treef9ef3febfd46bf4ac19678e2f5e14b45105e8f09 /doc
parent8cf8eb16ac873c11a6b1051c3a71a91659d431e3 (diff)
downloadandroid-node-v8-ae8f20ec5eee55f648823392c9c4e9491c958b60.tar.gz
android-node-v8-ae8f20ec5eee55f648823392c9c4e9491c958b60.tar.bz2
android-node-v8-ae8f20ec5eee55f648823392c9c4e9491c958b60.zip
events: add captureRejection option
PR-URL: https://github.com/nodejs/node/pull/27867 Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Michaƫl Zasso <targos@protonmail.com>
Diffstat (limited to 'doc')
-rw-r--r--doc/api/events.md125
1 files changed, 125 insertions, 0 deletions
diff --git a/doc/api/events.md b/doc/api/events.md
index ec6f608609..3a558ec233 100644
--- a/doc/api/events.md
+++ b/doc/api/events.md
@@ -155,9 +155,66 @@ myEmitter.emit('error', new Error('whoops!'));
// Prints: whoops! there was an error
```
+## Capture Rejections of Promises
+
+> Stability: 1 - captureRejections is experimental.
+
+Using `async` functions with event handlers is problematic, because it
+can lead to an unhandled rejection in case of a thrown exception:
+
+```js
+const ee = new EventEmitter();
+ee.on('something', async (value) => {
+ throw new Error('kaboom');
+});
+```
+
+The `captureRejections` option in the `EventEmitter` constructor or the global
+setting change this behavior, installing a `.then(undefined, handler)`
+handler on the `Promise`. This handler routes the exception
+asynchronously to the [`Symbol.for('nodejs.rejection')`][rejection] method
+if there is one, or to [`'error'`][error] event handler if there is none.
+
+```js
+const ee1 = new EventEmitter({ captureRejections: true });
+ee1.on('something', async (value) => {
+ throw new Error('kaboom');
+});
+
+ee1.on('error', console.log);
+
+const ee2 = new EventEmitter({ captureRejections: true });
+ee2.on('something', async (value) => {
+ throw new Error('kaboom');
+});
+
+ee2[Symbol.for('nodejs.rejection')] = console.log;
+```
+
+Setting `EventEmitter.captureRejections = true` will change the default for all
+new instances of `EventEmitter`.
+
+```js
+EventEmitter.captureRejections = true;
+const ee1 = new EventEmitter();
+ee1.on('something', async (value) => {
+ throw new Error('kaboom');
+});
+
+ee1.on('error', console.log);
+```
+
+The `'error'` events that are generated by the `captureRejections` behavior
+do not have a catch handler to avoid infinite error loops: the
+recommendation is to **not use `async` functions as `'error'` event handlers**.
+
## Class: EventEmitter
<!-- YAML
added: v0.1.26
+changes:
+ - version: REPLACEME
+ pr-url: https://github.com/nodejs/node/pull/27867
+ description: Added captureRejections option.
-->
The `EventEmitter` class is defined and exposed by the `events` module:
@@ -169,6 +226,12 @@ const EventEmitter = require('events');
All `EventEmitter`s emit the event `'newListener'` when new listeners are
added and `'removeListener'` when existing listeners are removed.
+It supports the following option:
+
+* `captureRejections` {boolean} It enables
+ [automatic capturing of promise rejection][capturerejections].
+ Default: `false`.
+
### Event: 'newListener'
<!-- YAML
added: v0.1.26
@@ -694,6 +757,42 @@ newListeners[0]();
emitter.emit('log');
```
+### emitter\[Symbol.for('nodejs.rejection')\](err, eventName\[, ...args\])
+<!-- YAML
+added: REPLACEME
+-->
+
+> Stability: 1 - captureRejections is experimental.
+
+* `err` Error
+* `eventName` {string|symbol}
+* `...args` {any}
+
+The `Symbol.for('nodejs.rejection')` method is called in case a
+promise rejection happens when emitting an event and
+[`captureRejections`][capturerejections] is enabled on the emitter.
+It is possible to use [`events.captureRejectionSymbol`][rejectionsymbol] in
+place of `Symbol.for('nodejs.rejection')`.
+
+```js
+const { EventEmitter, captureRejectionSymbol } = require('events');
+
+class MyClass extends EventEmitter {
+ constructor() {
+ super({ captureRejections: true });
+ }
+
+ [captureRejectionSymbol](err, event, ...args) {
+ console.log('rejection happened for', event, 'with', err, ...args);
+ this.destroy(err);
+ }
+
+ destroy(err) {
+ // Tear the resource down here.
+ }
+}
+```
+
## events.once(emitter, name)
<!-- YAML
added: v11.13.0
@@ -740,6 +839,28 @@ async function run() {
run();
```
+## events.captureRejections
+<!-- YAML
+added: REPLACEME
+-->
+
+> Stability: 1 - captureRejections is experimental.
+
+Value: {boolean}
+
+Change the default `captureRejections` option on all new `EventEmitter` objects.
+
+## events.captureRejectionSymbol
+<!-- YAML
+added: REPLACEME
+-->
+
+> Stability: 1 - captureRejections is experimental.
+
+Value: `Symbol.for('nodejs.rejection')`
+
+See how to write a custom [rejection handler][rejection].
+
[WHATWG-EventTarget]: https://dom.spec.whatwg.org/#interface-eventtarget
[`--trace-warnings`]: cli.html#cli_trace_warnings
[`EventEmitter.defaultMaxListeners`]: #events_eventemitter_defaultmaxlisteners
@@ -751,3 +872,7 @@ run();
[`net.Server`]: net.html#net_class_net_server
[`process.on('warning')`]: process.html#process_event_warning
[stream]: stream.html
+[capturerejections]: #events_capture_rejections_of_promises
+[rejection]: #events_emitter_symbol_for_nodejs_rejection_err_eventname_args
+[rejectionsymbol]: #events_events_capturerejectionsymbol
+[error]: #events_error_events