react-native: JS exceptions are hidden from developer when using Promises (async functions)
Take the following example, which (correctly) produces a redbox:
IntentAndroid.canOpenURL(url, (canOpen) => {
// Some code that can throw ...
throw new Error('This should redbox');
});
The Java signature is:
@ReactMethod
public void canOpenURL(String url, Callback callback)
Now change this to an async function:
@ReactMethod
public void canOpenURL(String url, Promise promise)
IntentAndroid.canOpenURL(url).then((canOpen) => {
// Some code that can throw ...
throw new Error('This should redbox');
});
No redbox is shown and nothing is logged which is in my opinion very poor developer experience. We’ve all been there - you’re trying to debug a program which doesn’t work but since there are no error messages and you have no idea what’s wrong.
The way to “fix” this is to call done()
:
IntentAndroid.canOpenURL(url).then((canOpen) => {
// Some code that can throw ...
throw new Error('This should redbox');
}).done(); // Now throws and produces a redbox
But this is super easy to forget 😦
For now, I’ll go with a callback in the IntentAndroid
. Feel like we need to find a good solution to this problem first before we migrate all APIs to async functions.
About this issue
- Original URL
- State: closed
- Created 9 years ago
- Comments: 29 (26 by maintainers)
Links to this issue
Commits related to this issue
- Make InteractionManager.runAfterInteractions() return a Promise Summary: In accordance with the unwritten rule that any API that takes a callback should also return a promise, I've changed `Interacti... — committed to facebook/react-native by philikon 9 years ago
- Add support for promise rejection tracking Summary: Adds support for tracking unhandled rejections with `console.warn` (= yellow box). I will create a follow-up with proper error stack formatting. ... — committed to wildlifela/react-native by davidaurelio 8 years ago
you should be able to paste this code into your app, and throw an error: https://github.com/facebook/react-native/blob/c6b96c0df789717d53ec520ad28ba0ae00db6ec2/Libraries/Promise.js#L17-L49
In case this does nothing, use
setImmediate
to throw outside of the promise rejection handlerdone()
is not part of the es2015 standard