Skip to content

Commit 9806950

Browse files
fortmarekospfranco
authored andcommittedDec 5, 2023
Symbolicate unhandled promise rejections (facebook#40914) (facebook#41377)
Summary: For a very long time when a promise rejects without an attached catch we get this warning screen without a correct stack trace, only some internal calls to the RN internals. <img src="https://github.com/facebook/react-native/assets/1634213/75aa7615-ee3e-4229-80d6-1744130de6e5" width="200" /> I created [an issue for discussion](react-native-community/discussions-and-proposals#718) in the react-native-community repo and we figured out it was only a matter of symbolication. While it cannot be done on release without external packages and source maps, at least while developing we can provide a symbolicated stack-trace so developers can better debug the source of rejected promise. I got the stack trace symbolicated and the correct code frame. I'm missing some help trying to display it in the warning view but at the very least I can now correctly show the line of the error and log the codeframe to the console. <!-- Help reviewers and the release process by writing your own changelog entry. Pick one each for the category and type tags: [GENERAL] [FIXED] - Show correct stack frame on unhandled promise rejections on development mode. For more details, see: https://reactnative.dev/contributing/changelogs-in-pull-requests Pull Request resolved: facebook#40914 Test Plan: I simply created a throwing function on a dummy app, and checked the output of the console and the warning view: ```ts import React from 'react'; import {SafeAreaView, Text} from 'react-native'; async function throwme() { throw new Error('UNHANDLED'); } function App(): JSX.Element { throwme(); return ( <SafeAreaView> <Text>Throw test</Text> </SafeAreaView> ); } export default App; ``` Here is the output <img src="https://github.com/facebook/react-native/assets/1634213/2c100e4d-618e-4143-8d64-4095e8370f4f" width="200" /> Edit: I got the warning window working properly: <img src="https://github.com/facebook/react-native/assets/1634213/f02a2568-da3e-4daa-8132-e05cbe591737" width="200" /> Reviewed By: yungsters Differential Revision: D50324344 Pulled By: javache fbshipit-source-id: 66850312d444cf1ae5333b493222ae0868d47056 Co-authored-by: Oscar Franco <[email protected]>
1 parent 44c33a7 commit 9806950

File tree

2 files changed

+23
-8
lines changed

2 files changed

+23
-8
lines changed
 

‎Libraries/LogBox/Data/LogBoxData.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ export type LogData = $ReadOnly<{|
3030
message: Message,
3131
category: Category,
3232
componentStack: ComponentStack,
33+
stack?: string,
3334
|}>;
3435

3536
export type Observer = (
@@ -198,7 +199,7 @@ export function addLog(log: LogData): void {
198199
// otherwise spammy logs would pause rendering.
199200
setImmediate(() => {
200201
try {
201-
const stack = parseErrorStack(errorForStackTrace?.stack);
202+
const stack = parseErrorStack(log.stack ?? errorForStackTrace?.stack);
202203

203204
appendNewLog(
204205
new LogBoxLog({

‎Libraries/promiseRejectionTrackingOptions.js

+21-7
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
import typeof {enable} from 'promise/setimmediate/rejection-tracking';
1212

13+
import LogBox from './LogBox/LogBox';
14+
1315
type ExtractOptionsType = <P>(((options?: ?P) => void)) => P;
1416

1517
let rejectionTrackingOptions: $Call<ExtractOptionsType, enable> = {
@@ -36,17 +38,29 @@ let rejectionTrackingOptions: $Call<ExtractOptionsType, enable> = {
3638
}
3739
}
3840

39-
const warning =
40-
`Possible Unhandled Promise Rejection (id: ${id}):\n` +
41-
`${message ?? ''}\n` +
42-
(stack == null ? '' : stack);
43-
console.warn(warning);
41+
const warning = `Possible unhandled promise rejection (id: ${id}):\n${
42+
message ?? ''
43+
}`;
44+
if (__DEV__) {
45+
LogBox.addLog({
46+
level: 'warn',
47+
message: {
48+
content: warning,
49+
substitutions: [],
50+
},
51+
componentStack: [],
52+
stack,
53+
category: 'possible_unhandled_promise_rejection',
54+
});
55+
} else {
56+
console.warn(warning);
57+
}
4458
},
4559
onHandled: id => {
4660
const warning =
47-
`Promise Rejection Handled (id: ${id})\n` +
61+
`Promise rejection handled (id: ${id})\n` +
4862
'This means you can ignore any previous messages of the form ' +
49-
`"Possible Unhandled Promise Rejection (id: ${id}):"`;
63+
`"Possible unhandled promise rejection (id: ${id}):"`;
5064
console.warn(warning);
5165
},
5266
};

0 commit comments

Comments
 (0)