caolan / caolan/highland

UnhandledPromiseRejectionWarning in node

Open
#694 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
JavaScript
Stars
3.4k
Forks
145
PR merge metrics
No merged PRs in 30d

Description

Hi!

I've been introducing highland into a Node project at work, and I've noticed that I get warnings from node in certain conditions.

Specifically, when I run this snippet:
```javascript
const oops = Promise.reject(new Error('muahaha'));
_(oops)
.toNodeStream()
.on('error', err => console.log('got it', err));
```
I see the following output:
```
(node:21215) UnhandledPromiseRejectionWarning: Error: muhahaha
at fail (repl:1:31)
at repl:1:3
at Script.runInThisContext (vm.js:122:20)
at REPLServer.defaultEval (repl.js:332:29)
at bound (domain.js:402:14)
at REPLServer.runBound [as eval] (domain.js:415:12)
at REPLServer.onLine (repl.js:642:10)
at REPLServer.emit (events.js:203:15)
at REPLServer.EventEmitter.emit (domain.js:448:20)
at REPLServer.Interface._onLine (readline.js:308:10)
(node:21215) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 21)
got it Error: muhahaha
at fail (repl:1:31)
at repl:1:3
at Script.runInThisContext (vm.js:122:20)
at REPLServer.defaultEval (repl.js:332:29)
at bound (domain.js:402:14)
at REPLServer.runBound [as eval] (domain.js:415:12)
at REPLServer.onLine (repl.js:642:10)
at REPLServer.emit (events.js:203:15)
at REPLServer.EventEmitter.emit (domain.js:448:20)
at REPLServer.Interface._onLine (readline.js:308:10)
(node:21215) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 21)
```

I think that this is happening because the [promiseStream function](https://github.com/caolan/highland/blob/2.x/lib/index.js#L520) is attaching the promise handlers inside of the new stream. Since the stream constructor is lazy when passed a function, the rejection handler is registered asynchronously; the rejection will be handled (assuming the stream is eventually consumed), but node still yells at me because it isn't handled right away.

Would it make sense to call `promise.then` synchronously when building the stream, to avoid this? I think if `promiseStream` constructed a new empty stream and used `write` when values were available, it could preserve its current behavior without triggering node warnings.

Contributor guide

Open the contributing guide

Research direction

Start with the promiseStream function in lib/index.js around the linked line, then reproduce the issue with the supplied Promise.reject and toNodeStream snippet. Check when the promise handlers are registered relative to stream consumption. Done means the rejection is delivered to the stream's error handler without Node's unhandled-rejection warnings, while existing stream behavior is preserved.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.