Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

[asyncify] Make errors in callbacks throw globally #1408

Merged
merged 1 commit into from
Apr 22, 2017

Conversation

davidaurelio
Copy link
Contributor

If asyncify wraps a function returning promises, the callback will be executed as part of the promise’s .then() method.
This means that any error thrown from that method will be silenced, and lead to a “unhandled promise rejection” warning in modern engines.

Usually, we want these errors to be visible, and even crash the process.

I’d like to add a test, but there doesn’t seem to be a good way to do it, especially for both node.js and browsers.

@davidaurelio
Copy link
Contributor Author

I’m going to fix the broken tests, but would like feedback on the change first.

@aearly
Copy link
Collaborator

aearly commented Apr 18, 2017

I've thought about deferring the callback in asyncify, for the reason you mention, but I don't like it because of the extra deferral.

Another strategy would be to try/catch the callback, and then re-throw the error on the next tick. This is what Bluebird does: https://github.com/petkaantonov/bluebird/blob/master/src/nodeify.js#L38-L42

Either way, if it involves changing our tests, it's a breaking change, albeit a small one.

Also, in the next version of Node, unhandled promise rejections are going to start killing the process, just like an unhandled error.

@aearly
Copy link
Collaborator

aearly commented Apr 18, 2017

Re. catching an async error, you can do this: https://github.com/caolan/async/blob/master/mocha_test/waterfall.js#L110-L119

@davidaurelio
Copy link
Contributor Author

davidaurelio commented Apr 19, 2017

Thanks for the hints. I updated the PR.

Another strategy would be to try/catch the callback, and then re-throw the error on the next tick

Seems the best way to do it. I adapted the code accordingly.

Either way, if it involves changing our tests, it's a breaking change, albeit a small one.

It is changing behavior, but you could argue it is a fix. The behavior is now the same as when asyncify’ing functions that don’t return promises. There’s even a test for errors to be thrown in the non-promise case.

If asyncify wraps a function returning promises, the callback will be executed as part of the promise’s `.then()` method.
This means that any error thrown from that method will be silenced, and lead to a “unhandled promise rejection” warning in modern engines.

Usually, we want these errors to be visible, and even crash the process.
Copy link
Collaborator

@megawac megawac left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 I consider this a bug fix

@aearly
Copy link
Collaborator

aearly commented Apr 20, 2017

You're right, after further thought, this is more of a bug fix. It will change how people's code behaves, though.

@aearly aearly merged commit dd7cf79 into caolan:master Apr 22, 2017
@aearly
Copy link
Collaborator

aearly commented Apr 29, 2017

Released in v2.4.0!

@davidaurelio
Copy link
Contributor Author

great, thanks for letting me know!

# for free to join this conversation on GitHub. Already have an account? # to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants