Consider this snippet:
const{ EventEmitter }=require('node:events')functionrun(name){returnnewPromise((resolve)=>{conste=newEventEmitter()process.nextTick(()=>{e.emit('error',newError())});resolve(e)}).then(((e)=>{e.on('error',err=>{console.error(`### ${name} ###`,err)})}))}queueMicrotask(run.bind(null,'queueMicrotask'))setImmediate(run.bind(null,'setImmediate'))This results in
### queueMicrotask ### Error
at /Users/matteo/c.cjs:7:23
at process.processTicksAndRejections (node:internal/process/task_queues:77:11)
node:events:492
throw er; // Unhandled 'error' event
^
Error
at /Users/matteo/c.cjs:7:23
at process.processTicksAndRejections (node:internal/process/task_queues:77:11)
Emitted 'error' event at:
at /Users/matteo/c.cjs:7:9
at process.processTicksAndRejections (node:internal/process/task_queues:77:11)
Node.js v20.10.0
Why is this an issue? In most part of Node.js core,
we use process.nextTick(() => ee.emit('error')) to let users install event handlers.
However, if an EventEmitter is returned by an async function, there is a significant possibility that the error could not be caught.
(This is essentially a problem for Node.js streams).
Consider this snippet:
This results in
Why is this an issue? In most part of Node.js core,
we use
process.nextTick(() => ee.emit('error'))to let users install event handlers.However, if an
EventEmitteris returned by anasync function, there is a significant possibility that the error could not be caught.(This is essentially a problem for Node.js streams).