-
Notifications
You must be signed in to change notification settings - Fork 24.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Error Reporting] Why do unhandled promises disappear? #2585
Comments
React Native uses its own Promises library so that it works on JSC. I suppose we could have it use the existing Promises library if one exists and polyfill in extension methods like done(). Cc @ForbesLindesay @vjeux |
@miracle2k you should call done() at the end of your promise chain which will log if there are unhandled exceptions. You'll want to do this anyway because it will give you the stack trace when running on any other JS engine. |
|
I don't follow the spec discussions very closely, but I got the impression that folks decided I am using redux and the redux-promise middleware, and it seems to me that really the right place for done() to be called is the middleware itself - which does not do this, presumably with the assumption too that it is not part of the spec. This just as a note as to why I would be happy to see the JS environment handle unrejected promises |
Thanks for chiming in y'all 😄
Since async/await have been officially enabled since 0.10.0-rc (release notes), would the equivalent be "try/catch is the recommended way of handling this"? I've had a weird issue that cost me some hours where rearranging my entry point JS import caused babel-core's core-js Promise implementation to be loaded before then/promise. |
If you await a promise (or return it) you don't need to call .done on it because the error will propagate naturally. You do need to remember that async functions still return promises, so you should call .done on any call to an async function where you're not awaiting the result. try/catch has the same problem as calling I'm not sure what do do about the babel-core implementation sneaking in. |
@ForbesLindesay Thanks for clearing that up!
Makes sense. So what about this? async function componentWillMount() {
throw new Error()
} I guess lifecycle methods shouldn't be made async, because react-native doesn't make any guarantees as to what happens with rejected Promises that are returned. So I should have put the async code into another async function, call that from Maybe react(-native) could either call |
Interesting point. I think react could at a minimum add a warning for that in development mode. It reminds me of C# which let you do Some form of type checker (e.g. flow) could be used to detect when you had forgotten to call notAwaitable(async function componentWillMount() {
throw new Error()
}) where function notAwaitable(fn) {
return function () {
fn.apply(this, arguments).done();
}
} With ES7 decorators, you could turn this into: @notAwaitable
async function componentWillMount() {
throw new Error()
} |
I wrote a decorator called autodone that calls @autodone
async componentDidMount() {
await somethingAsync();
} BTW it's kind of dangerous to use Promises/callbacks/await since the component can get unmounted between |
@ForbesLindesay @ide I like the decorator idea. This could also be a react-specific babel transform, since I'd like to have this on all my async methods.
Huh, that's a good point. It's just so darn convenient with await/async now. Could we:
|
@ehd want to raise those points in the react repo since they are about React in general? |
@ide Yes, good point. Will do :) |
This is related to #4142 |
I believe this is fixed now as unhandled promises produce warnings. |
@mkonicek Warnings are very short and not informative like
Console.log contains stack trace, but it is for bundle:
Is there any way to see normal stack trace? |
I'm not sure there's a good way to get around that. You could use the .done method to terminate promise chains, which would result in the proper stack trace. |
Would calling |
|
Calling .catch is a no-op unless you pass it an |
thanks for the info but can't use them for handling the last |
As discussed in #4142 (and thank you to @burgalon): // override RN's default promise implementation
// which is https://github.com/then/promise
import 'core-js';
window.onunhandledrejection = function(promise, reason) {
console.log('window.onunhandledrejection', promise, reason);
}; Works 👍 And if you want fancier logging, you can use the |
Summary: Adds support for tracking unhandled rejections with `console.warn` (= yellow box). I will create a follow-up with proper error stack formatting. related: #4971 fixes: #4045, #4142 public {F59857438} {F59857439} Reviewed By: bestander Differential Revision: D2803126 fb-gh-sync-id: 376b33e42a967675a04338cbff3ec315a77d1037
Hey, I can confirm it seems to work. Does importing core-js have other effects that could be armful to my app? |
Note that core-js doesn't have the .finally() method in former versions, you need at least release 2.5.0 Even with adding this version to my package.json it seems that it still fails to call finally, and I also have propTypes warning due to |
react-native's error reporting is excellent, but I've started to use promises now, and I see them swallow all kinds of errors now.
When developing in Chrome these days, unhandled, rejected promises leave a stracktrace in the console. When I am debugging react-native apps in Chrome, the JavaScript is being executed in Chrome also, says the documentation.
What is the reason I don't receive the stracktrace?
The text was updated successfully, but these errors were encountered: