Skip to content

Commit

Permalink
POC: Mixed stack traces for Android and iOS Turbo Modules (facebook#3…
Browse files Browse the repository at this point in the history
…6925)

Summary:
This is a POC of how the platform and native exceptions could be passed to the JS layer to get the full stack trace from a JS call to the platform stack trace where an error occurred. This is a follow-up on [the Better Error Reporting Post](reactwg/react-native-new-architecture#122).

At the moment this works for sync calls only. The calls are wrapped in try-catch and platform exceptions are passed in JS Error cause with `name`, `message`, and `stack`. Throwables have an extra `stackArray` to pass structured stack information.

## Future:

Extract the error assembly to a separate function and add tests.

How to utilize `callStackReturnAddresses` on iOS and what structure information about the stack could be passed to JS?

RedBox in JS should display the JS Error with cause -> the platform error and its stack trace. Currently, only the JS stack is shown in the RedBox.

## Changelog:

<!-- Help reviewers and the release process by writing your own changelog entry.

Pick one each for the category and type tags:

[ANDROID|GENERAL|IOS|INTERNAL] [BREAKING|ADDED|CHANGED|DEPRECATED|REMOVED|FIXED|SECURITY] - Message

For more details, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests
-->

[GENERAL][ADDED] - TBA

Pull Request resolved: facebook#36925

Test Plan:
| iOS | Android |
|--------|--------|
| ![ios-error-cause](https://user-images.githubusercontent.com/31292499/232463156-a4ebc698-ca1f-439f-8f3f-91738b5a0a1c.png) | ![android-error-cause](https://user-images.githubusercontent.com/31292499/232463137-9712d06a-7c02-4483-a136-55e49d71300a.png) |

Example of Throwable in JS:
```json
{
  "name": "Error",
  "message": "Exception in HostFunction: Intentional exception from JVM getObjectThrows with {\"c\":null,\"b\":\"foo\",\"a\":1}",
  "stack": "[native code]\ngetObjectThrows@http://10.0.2.2:8081/js/RNTesterApp.android.bundle?platform=android&dev=true&minify=false&app=com.facebook.react.uiapp&modulesOnly=false&runModule=true:129497:129\nonPress@http://10.0.2.2:8081/js/RNTesterApp.android.bundle?platform=android&dev=true&minify=false&app=com.facebook.react.uiapp&modulesOnly=false&runModule=true:129626:71\n_performTransitionSideEffects@http://10.0.2.2:8081/js/RNTesterApp.android.bundle?platform=android&dev=true&minify=false&app=com.facebook.react.uiapp&modulesOnly=false&runModule=true:51558:22\n_receiveSignal@http://10.0.2.2:8081/js/RNTesterApp.android.bundle?platform=android&dev=true&minify=false&app=com.facebook.react.uiapp&modulesOnly=false&runModule=true:51514:45\nonResponderRelease@http://10.0.2.2:8081/js/RNTesterApp.android.bundle?platform=android&dev=true&minify=false&app=com.facebook.react.uiapp&modulesOnly=false&runModule=true:51377:34\ninvokeGuardedCallbackProd@http://10.0.2.2:8081/js/RNTesterApp.android.bundle?platform=android&dev=true&minify=false&app=com.facebook.react.uiapp&modulesOnly=false&runModule=true:3292:21\ninvokeGuardedCallback@http://10.0.2.2:8081/js/RNTesterApp.android.bundle?platform=android&dev=true&minify=false&app=com.facebook.react.uiapp&modulesOnly=false&runModule=true:3378:42\ninvokeGuardedCallbackAndCatchFirstError@http://10.0.2.2:8081/js/RNTesterApp.android.bundle?platform=android&dev=true&minify=false&app=com.facebook.react.uiapp&modulesOnly=false&runModule=true:3381:36\nexecuteDispatch@http://10.0.2.2:8081/js/RNTesterApp.android.bundle?platform=android&dev=true&minify=false&app=com.facebook.react.uiapp&modulesOnly=false&runModule=true:3445:48\nexecuteDispatchesInOrder@http://10.0.2.2:8081/js/RNTesterApp.android.bundle?platform=android&dev=true&minify=false&app=com.facebook.react.uiapp&modulesOnly=false&runModule=true:3462:26\nexecuteDispatchesAndRelease@http://10.0.2.2:8081/js/RNTesterApp.android.bundle?platform=android&dev=true&minify=false&app=com.facebook.react.uiapp&modulesOnly=false&runModule=true:5186:35\nforEach@[native code]\nforEachAccumulated@http://10.0.2.2:8081/js/RNTesterApp.android.bundle?platform=android&dev=true&minify=false&app=com.facebook.react.uiapp&modulesOnly=false&runModule=true:3904:22\nrunEventsInBatch@http://10.0.2.2:8081/js/RNTesterApp.android.bundle?platform=android&dev=true&minify=false&app=com.facebook.react.uiapp&modulesOnly=false&runModule=true:5204:27\nrunExtractedPluginEventsInBatch@http://10.0.2.2:8081/js/RNTesterApp.android.bundle?platform=android&dev=true&minify=false&app=com.facebook.react.uiapp&modulesOnly=false&runModule=true:5226:25\nhttp://10.0.2.2:8081/js/RNTesterApp.android.bundle?platform=android&dev=true&minify=false&app=com.facebook.react.uiapp&modulesOnly=false&runModule=true:5244:42\nbatchedUpdates$1@http://10.0.2.2:8081/js/RNTesterApp.android.bundle?platform=android&dev=true&minify=false&app=com.facebook.react.uiapp&modulesOnly=false&runModule=true:15080:20\nbatchedUpdates@http://10.0.2.2:8081/js/RNTesterApp.android.bundle?platform=android&dev=true&minify=false&app=com.facebook.react.uiapp&modulesOnly=false&runModule=true:5175:36\ndispatchEvent@http://10.0.2.2:8081/js/RNTesterApp.android.bundle?platform=android&dev=true&minify=false&app=com.facebook.react.uiapp&modulesOnly=false&runModule=true:5237:23",
  "cause": {
    "name": "java.lang.RuntimeException",
    "message": "Intentional exception from JVM getObjectThrows with {\"c\":null,\"b\":\"foo\",\"a\":1}",
    "stack": "com.facebook.fbreact.specs.SampleTurboModule.getObjectThrows(SampleTurboModule.java:194)\ncom.facebook.jni.NativeRunnable.run(Native Method)\nandroid.os.Handler.handleCallback(Handler.java:942)\nandroid.os.Handler.dispatchMessage(Handler.java:99)\ncom.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage(MessageQueueThreadHandler.java:27)\nandroid.os.Looper.loopOnce(Looper.java:201)\nandroid.os.Looper.loop(Looper.java:288)\ncom.facebook.react.bridge.queue.MessageQueueThreadImpl$4.run(MessageQueueThreadImpl.java:228)\njava.lang.Thread.run(Thread.java:1012)\n",
    "stackArray": [
      {
        "className": "com.facebook.fbreact.specs.SampleTurboModule",
        "fileName": "SampleTurboModule.java",
        "lineNumber": 194,
        "methodName": "getObjectThrows"
      },
      {
        "className": "com.facebook.jni.NativeRunnable",
        "fileName": "NativeRunnable.java",
        "lineNumber": -2,
        "methodName": "run"
      },
      {
        "className": "android.os.Handler",
        "fileName": "Handler.java",
        "lineNumber": 942,
        "methodName": "handleCallback"
      },
      {
        "className": "android.os.Handler",
        "fileName": "Handler.java",
        "lineNumber": 99,
        "methodName": "dispatchMessage"
      },
      {
        "className": "com.facebook.react.bridge.queue.MessageQueueThreadHandler",
        "fileName": "MessageQueueThreadHandler.java",
        "lineNumber": 27,
        "methodName": "dispatchMessage"
      },
      {
        "className": "android.os.Looper",
        "fileName": "Looper.java",
        "lineNumber": 201,
        "methodName": "loopOnce"
      },
      {
        "className": "android.os.Looper",
        "fileName": "Looper.java",
        "lineNumber": 288,
        "methodName": "loop"
      },
      {
        "className": "com.facebook.react.bridge.queue.MessageQueueThreadImpl$4",
        "fileName": "MessageQueueThreadImpl.java",
        "lineNumber": 228,
        "methodName": "run"
      },
      {
        "className": "java.lang.Thread",
        "fileName": "Thread.java",
        "lineNumber": 1012,
        "methodName": "run"
      }
    ]
  },
  "line": 129497,
  "column": 129,
  "sourceURL": "http://10.0.2.2:8081/js/RNTesterApp.android.bundle?platform=android&dev=true&minify=false&app=com.facebook.react.uiapp&modulesOnly=false&runModule=true"
}
```

Example of NSException in JS:

```json
{
  "name": "Error",
  "message": "Exception in HostFunction: Intentional exception from ObjC getObjectThrows",
  "stack": "@[native code]\ngetObjectThrows@http://localhost:8081/js/RNTesterApp.ios.bundle:125422:129\nonPress@http://localhost:8081/js/RNTesterApp.ios.bundle:125549:71\n_performTransitionSideEffects@http://localhost:8081/js/RNTesterApp.ios.bundle:51025:22\n_receiveSignal@http://localhost:8081/js/RNTesterApp.ios.bundle:50981:45\nonResponderRelease@http://localhost:8081/js/RNTesterApp.ios.bundle:50844:34\ninvokeGuardedCallbackProd@http://localhost:8081/js/RNTesterApp.ios.bundle:3232:21\ninvokeGuardedCallback@http://localhost:8081/js/RNTesterApp.ios.bundle:3318:42\ninvokeGuardedCallbackAndCatchFirstError@http://localhost:8081/js/RNTesterApp.ios.bundle:3321:36\nexecuteDispatch@http://localhost:8081/js/RNTesterApp.ios.bundle:3385:48\nexecuteDispatchesInOrder@http://localhost:8081/js/RNTesterApp.ios.bundle:3402:26\nexecuteDispatchesAndRelease@http://localhost:8081/js/RNTesterApp.ios.bundle:5126:35\nforEach@[native code]\nforEachAccumulated@http://localhost:8081/js/RNTesterApp.ios.bundle:3844:22\nrunEventsInBatch@http://localhost:8081/js/RNTesterApp.ios.bundle:5144:27\nrunExtractedPluginEventsInBatch@http://localhost:8081/js/RNTesterApp.ios.bundle:5166:25\n@http://localhost:8081/js/RNTesterApp.ios.bundle:5184:42\nbatchedUpdates$1@http://localhost:8081/js/RNTesterApp.ios.bundle:15020:20\nbatchedUpdates@http://localhost:8081/js/RNTesterApp.ios.bundle:5115:36\ndispatchEvent@http://localhost:8081/js/RNTesterApp.ios.bundle:5177:23",
  "cause": {
    "name": "Excepption",
    "message": "Intentional exception from ObjC getObjectThrows",
    "stack": "0   CoreFoundation                      0x0000000180437330 __exceptionPreprocess + 172\n1   libobjc.A.dylib                     0x0000000180051274 objc_exception_throw + 56\n2   RNTester                            0x0000000103535900 -[RCTSampleTurboModule getObjectThrows:] + 120\n3   CoreFoundation                      0x000000018043d6c0 __invoking___ + 144\n4   CoreFoundation                      0x000000018043aa44 -[NSInvocation invoke] + 276\n5   CoreFoundation                      0x000000018043acdc -[NSInvocation invokeWithTarget:] + 60\n6   RNTester                            0x00000001032b066c ___ZN8facebook5react15ObjCTurboModule23performMethodInvocationERNS_3jsi7RuntimeENS0_26TurboModuleMethodValueKindEPKcP12NSInvocationP14NSMutableArray_block_invoke + 244\n7   RNTester                            0x00000001032afe68 _ZN8facebook5react15ObjCTurboModule23performMethodInvocationERNS_3jsi7RuntimeENS0_26TurboModuleMethodValueKindEPKcP12NSInvocationP14NSMutableArray + 528\n8   RNTester                            0x00000001032b38f0 _ZN8facebook5react15ObjCTurboModule16invokeObjCMethodERNS_3jsi7RuntimeENS0_26TurboModuleMethodValueKindERKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEEP13objc_selectorPKNS2_5ValueEm + 608\n9   RNTester                            0x0000000103533c18 _ZN8facebook5reactL61__hostFunction_NativeSampleTurboModuleSpecJSI_getObjectThrowsERNS_3jsi7RuntimeERNS0_11TurboModuleEPKNS1_5ValueEm + 112\n10  RNTester                            0x0000000102f1b0c4 _ZZN8facebook5react11TurboModule6createERNS_3jsi7RuntimeERKNS2_10PropNameIDEENKUlS4_RKNS2_5ValueEPS9_mE_clES4_SA_SB_m + 68\n11  RNTester                            0x0000000102f1b074 _ZNSt3__18__invokeB6v15006IRZN8facebook5react11TurboModule6createERNS1_3jsi7RuntimeERKNS4_10PropNameIDEEUlS6_RKNS4_5ValueEPSB_mE_JS6_SC_SD_mEEEDTclclsr3stdE7declvalIT_EEspclsr3stdE7declvalIT0_EEEEOSG_DpOSH_ + 72\n12  RNTester                            0x0000000102f1affc _ZNSt3__128__invoke_void_return_wrapperIN8facebook3jsi5ValueELb0EE6__callIJRZNS1_5react11TurboModule6createERNS2_7RuntimeERKNS2_10PropNameIDEEUlS9_RKS3_PSD_mE_S9_SE_SF_mEEES3_DpOT_ + 64\n13  RNTester                            0x0000000102f1afb0 _ZNSt3__110__function12__alloc_funcIZN8facebook5react11TurboModule6createERNS2_3jsi7RuntimeERKNS5_10PropNameIDEEUlS7_RKNS5_5ValueEPSC_mE_NS_9allocatorISF_EEFSB_S7_SD_SE_mEEclB6v15006ES7_SD_OSE_Om + 72\n14  RNTester                            0x0000000102f19f60 _ZNSt3__110__function6__funcIZN8facebook5react11TurboModule6createERNS2_3jsi7RuntimeERKNS5_10PropNameIDEEUlS7_RKNS5_5ValueEPSC_mE_NS_9allocatorISF_EEFSB_S7_SD_SE_mEEclES7_SD_OSE_Om + 68\n15  RNTester                            0x00000001034df970 _ZNKSt3__110__function12__value_funcIFN8facebook3jsi5ValueERNS3_7RuntimeERKS4_PS7_mEEclB6v15006ES6_S8_OS9_Om + 112\n16  RNTester                            0x00000001034df374 _ZNKSt3__18functionIFN8facebook3jsi5ValueERNS2_7RuntimeERKS3_PS6_mEEclES5_S7_S8_m + 72\n17  RNTester                            0x00000001034deaac _ZZN8facebook3jsc10JSCRuntime30createFunctionFromHostFunctionERKNS_3jsi10PropNameIDEjNSt3__18functionIFNS2_5ValueERNS2_7RuntimeERKS8_PSB_mEEEEN20HostFunctionMetadata4callEPK15OpaqueJSContextP13OpaqueJSValueSL_mPKPKSK_PSN_ + 720\n18  JavaScriptCore                      0x000000010a56e754 _ZN3JSCL34callJSNonFinalObjectCallbackObjectEPNS_14JSGlobalObjectEPNS_9CallFrameE + 436\n19  JavaScriptCore                      0x000000010ad60b78 _ZN3JSC14handleHostCallEPNS_14JSGlobalObjectEPNS_9CallFrameENS_7JSValueEPNS_12CallLinkInfoE + 1016\n20  JavaScriptCore                      0x000000010ad169dc operationLinkCall + 156\n21  ???                                 0x0000000280004330 0x0 + 10737435440\n22  JavaScriptCore                      0x000000010a4bba08 llint_entry + 147988\n23  JavaScriptCore                      0x000000010a4bba08 llint_entry + 147988\n24  JavaScriptCore                      0x000000010a4bba08 llint_entry + 147988\n25  JavaScriptCore                      0x000000010a4bb978 llint_entry + 147844\n26  JavaScriptCore                      0x000000010a4bb978 llint_entry + 147844\n27  ???                                 0x0000000280325200 0x0 + 10740716032\n28  ???                                 0x000000028025f558 0x0 + 10739905880\n29  ???                                 0x000000028025ed34 0x0 + 10739903796\n30  ???                                 0x00000002803deac4 0x0 + 10741476036\n31  ???                                 0x00000002802b7d4c 0x0 + 10740268364\n32  ???                                 0x00000002801b2b40 0x0 + 10739198784\n33  ???                                 0x0000000280385c74 0x0 + 10741111924\n34  ???                                 0x0000000280384a7c 0x0 + 10741107324\n35  ???                                 0x0000000280255920 0x0 + 10739865888\n36  ???                                 0x00000002801a7dfc 0x0 + 10739154428\n37  ???                                 0x00000002802c6d00 0x0 + 10740329728\n38  JavaScriptCore                      0x000000010a497550 vmEntryToJavaScript + 256\n39  JavaScriptCore                      0x000000010ac69b2c _ZN3JSC11Interpreter11executeCallEPNS_14JSGlobalObjectEPNS_8JSObjectERKNS_8CallDataENS_7JSValueERKNS_7ArgListE + 496\n40  JavaScriptCore                      0x000000010a57fd6c JSObjectCallAsFunction + 612\n41  RNTester                            0x00000001034da610 _ZN8facebook3jsc10JSCRuntime4callERKNS_3jsi8FunctionERKNS2_5ValueEPS7_m + 268\n42  RNTester                            0x00000001034e69c4 _ZNK8facebook3jsi8Function4callERNS0_7RuntimeEPKNS0_5ValueEm + 100\n43  RNTester                            0x00000001034e6954 _ZNK8facebook3jsi8Function4callERNS0_7RuntimeESt16initializer_listINS0_5ValueEE + 112\n44  RNTester                            0x000000010323ea78 _ZNK8facebook5react16UIManagerBinding13dispatchEventERNS_3jsi7RuntimeEPKNS0_11EventTargetERKNSt3__112basic_stringIcNS8_11char_traitsIcEENS8_9allocatorIcEEEENS0_18ReactEventPriorityERKNS8_8functionIFNS2_5ValueES4_EEE + 656\n45  RNTester                            0x000000010318d5bc _ZZZN8facebook5react9SchedulerC1ERKNS0_16SchedulerToolboxEPNS0_26UIManagerAnimationDelegateEPNS0_17SchedulerDelegateEENK3$_0clERNS_3jsi7RuntimeEPKNS0_11EventTargetERKNSt3__112basic_stringIcNSG_11char_traitsIcEENSG_9allocatorIcEEEENS0_18ReactEventPriorityERKNSG_8functionIFNSA_5ValueESC_EEEENKUlRKNS0_16UIManagerBindingEE_clESY_ + 60\n46  RNTester                            0x000000010318d574 _ZNSt3__18__invokeB6v15006IRZZN8facebook5react9SchedulerC1ERKNS2_16SchedulerToolboxEPNS2_26UIManagerAnimationDelegateEPNS2_17SchedulerDelegateEENK3$_0clERNS1_3jsi7RuntimeEPKNS2_11EventTargetERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEENS2_18ReactEventPriorityERKNS_8functionIFNSC_5ValueESE_EEEEUlRKNS2_16UIManagerBindingEE_JSZ_EEEDTclclsr3stdE7declvalIT_EEspclsr3stdE7declvalIT0_EEEEOS12_DpOS13_ + 32\n47  RNTester                            0x000000010318d524 _ZNSt3__128__invoke_void_return_wrapperIvLb1EE6__callIJRZZN8facebook5react9SchedulerC1ERKNS4_16SchedulerToolboxEPNS4_26UIManagerAnimationDelegateEPNS4_17SchedulerDelegateEENK3$_0clERNS3_3jsi7RuntimeEPKNS4_11EventTargetERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEENS4_18ReactEventPriorityERKNS_8functionIFNSE_5ValueESG_EEEEUlRKNS4_16UIManagerBindingEE_S11_EEEvDpOT_ + 32\n48  RNTester                            0x000000010318d4f8 _ZNSt3__110__function12__alloc_funcIZZN8facebook5react9SchedulerC1ERKNS3_16SchedulerToolboxEPNS3_26UIManagerAnimationDelegateEPNS3_17SchedulerDelegateEENK3$_0clERNS2_3jsi7RuntimeEPKNS3_11EventTargetERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEENS3_18ReactEventPriorityERKNS_8functionIFNSD_5ValueESF_EEEEUlRKNS3_16UIManagerBindingEE_NSM_IS11_EEFvS10_EEclB6v15006ES10_ + 36\n49  RNTester                            0x000000010318c4d0 _ZNSt3__110__function6__funcIZZN8facebook5react9SchedulerC1ERKNS3_16SchedulerToolboxEPNS3_26UIManagerAnimationDelegateEPNS3_17SchedulerDelegateEENK3$_0clERNS2_3jsi7RuntimeEPKNS3_11EventTargetERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEENS3_18ReactEventPriorityERKNS_8functionIFNSD_5ValueESF_EEEEUlRKNS3_16UIManagerBindingEE_NSM_IS11_EEFvS10_EEclES10_ + 36\n50  RNTester                            0x000000010323add4 _ZNKSt3__110__function12__value_funcIFvRKN8facebook5react16UIManagerBindingEEEclB6v15006ES6_ + 76\n51  RNTester                            0x000000010321ee80 _ZNKSt3__18functionIFvRKN8facebook5react16UIManagerBindingEEEclES5_ + 32\n52  RNTester                            0x000000010321ee24 _ZNK8facebook5react9UIManager12visitBindingERKNSt3__18functionIFvRKNS0_16UIManagerBindingEEEERNS_3jsi7RuntimeE + 84\n53  RNTester                            0x000000010318ba9c _ZZN8facebook5react9SchedulerC1ERKNS0_16SchedulerToolboxEPNS0_26UIManagerAnimationDelegateEPNS0_17SchedulerDelegateEENK3$_0clERNS_3jsi7RuntimeEPKNS0_11EventTargetERKNSt3__112basic_stringIcNSG_11char_traitsIcEENSG_9allocatorIcEEEENS0_18ReactEventPriorityERKNSG_8functionIFNSA_5ValueESC_EEE + 156\n54  RNTester                            0x000000010318b9f4 _ZNSt3__18__invokeB6v15006IRZN8facebook5react9SchedulerC1ERKNS2_16SchedulerToolboxEPNS2_26UIManagerAnimationDelegateEPNS2_17SchedulerDelegateEE3$_0JRNS1_3jsi7RuntimeEPKNS2_11EventTargetERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEENS2_18ReactEventPriorityERKNS_8functionIFNSD_5ValueESF_EEEEEEDTclclsr3stdE7declvalIT_EEspclsr3stdE7declvalIT0_EEEEOSY_DpOSZ_ + 72\n55  RNTester                            0x000000010318b97c _ZNSt3__128__invoke_void_return_wrapperIvLb1EE6__callIJRZN8facebook5react9SchedulerC1ERKNS4_16SchedulerToolboxEPNS4_26UIManagerAnimationDelegateEPNS4_17SchedulerDelegateEE3$_0RNS3_3jsi7RuntimeEPKNS4_11EventTargetERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEENS4_18ReactEventPriorityERKNS_8functionIFNSF_5ValueESH_EEEEEEvDpOT_ + 64\n56  RNTester                            0x000000010318b930 _ZNSt3__110__function12__alloc_funcIZN8facebook5react9SchedulerC1ERKNS3_16SchedulerToolboxEPNS3_26UIManagerAnimationDelegateEPNS3_17SchedulerDelegateEE3$_0NS_9allocatorISC_EEFvRNS2_3jsi7RuntimeEPKNS3_11EventTargetERKNS_12basic_stringIcNS_11char_traitsIcEENSD_IcEEEENS3_18ReactEventPriorityERKNS_8functionIFNSF_5ValueESH_EEEEEclB6v15006ESH_OSK_SR_OSS_SY_ + 68\n57  RNTester                            0x000000010318a6b0 _ZNSt3__110__function6__funcIZN8facebook5react9SchedulerC1ERKNS3_16SchedulerToolboxEPNS3_26UIManagerAnimationDelegateEPNS3_17SchedulerDelegateEE3$_0NS_9allocatorISC_EEFvRNS2_3jsi7RuntimeEPKNS3_11EventTargetERKNS_12basic_stringIcNS_11char_traitsIcEENSD_IcEEEENS3_18ReactEventPriorityERKNS_8functionIFNSF_5ValueESH_EEEEEclESH_OSK_SR_OSS_SY_ + 68\n58  RNTester                            0x00000001030c2e60 _ZNKSt3__110__function12__value_funcIFvRN8facebook3jsi7RuntimeEPKNS2_5react11EventTargetERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEENS6_18ReactEventPriorityERKNS_8functionIFNS3_5ValueES5_EEEEEclB6v15006ES5_OS9_SH_OSI_SO_ + 108\n59  RNTester                            0x00000001030c28d4 _ZNKSt3__18functionIFvRN8facebook3jsi7RuntimeEPKNS1_5react11EventTargetERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEENS5_18ReactEventPriorityERKNS0_IFNS2_5ValueES4_EEEEEclES4_S8_SG_SH_SM_ + 72\n60  RNTester                            0x00000001030c26c4 _ZNK8facebook5react19EventQueueProcessor11flushEventsERNS_3jsi7RuntimeEONSt3__16vectorINS0_8RawEventENS5_9allocatorIS7_EEEE + 516\n61  RNTester                            0x00000001030bd58c _ZNK8facebook5react10EventQueue11flushEventsERNS_3jsi7RuntimeE + 196\n62  RNTester                            0x00000001030bd3d8 _ZNK8facebook5react10EventQueue6onBeatERNS_3jsi7RuntimeE + 44\n63  RNTester                            0x00000001030bf6b0 _ZZN8facebook5react10EventQueueC1ENS0_19EventQueueProcessorENSt3__110unique_ptrINS0_9EventBeatENS3_14default_deleteIS5_EEEEENK3$_0clERNS_3jsi7RuntimeE + 36\n64  RNTester                            0x00000001030bf680 _ZNSt3__18__invokeB6v15006IRZN8facebook5react10EventQueueC1ENS2_19EventQueueProcessorENS_10unique_ptrINS2_9EventBeatENS_14default_deleteIS6_EEEEE3$_0JRNS1_3jsi7RuntimeEEEEDTclclsr3stdE7declvalIT_EEspclsr3stdE7declvalIT0_EEEEOSF_DpOSG_ + 32\n65  RNTester                            0x00000001030bf630 _ZNSt3__128__invoke_void_return_wrapperIvLb1EE6__callIJRZN8facebook5react10EventQueueC1ENS4_19EventQueueProcessorENS_10unique_ptrINS4_9EventBeatENS_14default_deleteIS8_EEEEE3$_0RNS3_3jsi7RuntimeEEEEvDpOT_ + 32\n66  RNTester                            0x00000001030bf604 _ZNSt3__110__function12__alloc_funcIZN8facebook5react10EventQueueC1ENS3_19EventQueueProcessorENS_10unique_ptrINS3_9EventBeatENS_14default_deleteIS7_EEEEE3$_0NS_9allocatorISB_EEFvRNS2_3jsi7RuntimeEEEclB6v15006ESG_ + 36\n67  RNTester                            0x00000001030be470 _ZNSt3__110__function6__funcIZN8facebook5react10EventQueueC1ENS3_19EventQueueProcessorENS_10unique_ptrINS3_9EventBeatENS_14default_deleteIS7_EEEEE3$_0NS_9allocatorISB_EEFvRNS2_3jsi7RuntimeEEEclESG_ + 36\n68  RNTester                            0x0000000102c2f1cc _ZNKSt3__110__function12__value_funcIFvRN8facebook3jsi7RuntimeEEEclB6v15006ES5_ + 76\n69  RNTester                            0x0000000102c2f174 _ZNKSt3__18functionIFvRN8facebook3jsi7RuntimeEEEclES4_ + 32\n70  RNTester                            0x000000010306a0cc _ZZNK8facebook5react21AsynchronousEventBeat6induceEvENK3$_0clERNS_3jsi7RuntimeE + 136\n71  RNTester                            0x000000010306a038 _ZNSt3__18__invokeB6v15006IRZNK8facebook5react21AsynchronousEventBeat6induceEvE3$_0JRNS1_3jsi7RuntimeEEEEDTclclsr3stdE7declvalIT_EEspclsr3stdE7declvalIT0_EEEEOS9_DpOSA_ + 32\n72  RNTester                            0x0000000103069fe8 _ZNSt3__128__invoke_void_return_wrapperIvLb1EE6__callIJRZNK8facebook5react21AsynchronousEventBeat6induceEvE3$_0RNS3_3jsi7RuntimeEEEEvDpOT_ + 32\n73  RNTester                            0x0000000103069fbc _ZNSt3__110__function12__alloc_funcIZNK8facebook5react21AsynchronousEventBeat6induceEvE3$_0NS_9allocatorIS5_EEFvRNS2_3jsi7RuntimeEEEclB6v15006ESA_ + 36\n74  RNTester                            0x0000000103068cf8 _ZNSt3__110__function6__funcIZNK8facebook5react21AsynchronousEventBeat6induceEvE3$_0NS_9allocatorIS5_EEFvRNS2_3jsi7RuntimeEEEclESA_ + 36\n75  RNTester                            0x0000000102c2f1cc _ZNKSt3__110__function12__value_funcIFvRN8facebook3jsi7RuntimeEEEclB6v15006ES5_ + 76\n76  RNTester                            0x0000000102c2f174 _ZNKSt3__18functionIFvRN8facebook3jsi7RuntimeEEEclES4_ + 32\n77  RNTester                            0x0000000103169304 _ZZNK8facebook5react16RuntimeScheduler12scheduleWorkENSt3__18functionIFvRNS_3jsi7RuntimeEEEEENK3$_0clES6_ + 64\n78  RNTester                            0x00000001031692b8 _ZNSt3__18__invokeB6v15006IRZNK8facebook5react16RuntimeScheduler12scheduleWorkENS_8functionIFvRNS1_3jsi7RuntimeEEEEE3$_0JS7_EEEDTclclsr3stdE7declvalIT_EEspclsr3stdE7declvalIT0_EEEEOSC_DpOSD_ + 32\n79  RNTester                            0x0000000103169268 _ZNSt3__128__invoke_void_return_wrapperIvLb1EE6__callIJRZNK8facebook5react16RuntimeScheduler12scheduleWorkENS_8functionIFvRNS3_3jsi7RuntimeEEEEE3$_0S9_EEEvDpOT_ + 32\n80  RNTester                            0x000000010316923c _ZNSt3__110__function12__alloc_funcIZNK8facebook5react16RuntimeScheduler12scheduleWorkENS_8functionIFvRNS2_3jsi7RuntimeEEEEE3$_0NS_9allocatorISB_EES9_EclB6v15006ES8_ + 36\n81  RNTester                            0x0000000103167fe8 _ZNSt3__110__function6__funcIZNK8facebook5react16RuntimeScheduler12scheduleWorkENS_8functionIFvRNS2_3jsi7RuntimeEEEEE3$_0NS_9allocatorISB_EES9_EclES8_ + 36\n82  RNTester                            0x0000000102c2f1cc _ZNKSt3__110__function12__value_funcIFvRN8facebook3jsi7RuntimeEEEclB6v15006ES5_ + 76\n83  RNTester                            0x0000000102c2f174 _ZNKSt3__18functionIFvRN8facebook3jsi7RuntimeEEEclES4_ + 32\n84  RNTester                            0x00000001033d56e8 _ZZZ28RCTRuntimeExecutorFromBridgeP9RCTBridgeENK3$_0clEONSt3__18functionIFvRN8facebook3jsi7RuntimeEEEEENKUlvE_clEv + 724\n85  RNTester                            0x00000001033d5408 _ZNSt3__18__invokeB6v15006IRZZ28RCTRuntimeExecutorFromBridgeP9RCTBridgeENK3$_0clEONS_8functionIFvRN8facebook3jsi7RuntimeEEEEEUlvE_JEEEDTclclsr3stdE7declvalIT_EEspclsr3stdE7declvalIT0_EEEEOSE_DpOSF_ + 24\n86  RNTester                            0x00000001033d53c0 _ZNSt3__128__invoke_void_return_wrapperIvLb1EE6__callIJRZZ28RCTRuntimeExecutorFromBridgeP9RCTBridgeENK3$_0clEONS_8functionIFvRN8facebook3jsi7RuntimeEEEEEUlvE_EEEvDpOT_ + 24\n87  RNTester                            0x00000001033d539c _ZNSt3__110__function12__alloc_funcIZZ28RCTRuntimeExecutorFromBridgeP9RCTBridgeENK3$_0clEONS_8functionIFvRN8facebook3jsi7RuntimeEEEEEUlvE_NS_9allocatorISD_EEFvvEEclB6v15006Ev + 28\n88  RNTester                            0x00000001033d4128 _ZNSt3__110__function6__funcIZZ28RCTRuntimeExecutorFromBridgeP9RCTBridgeENK3$_0clEONS_8functionIFvRN8facebook3jsi7RuntimeEEEEEUlvE_NS_9allocatorISD_EEFvvEEclEv + 28\n89  RNTester                            0x0000000102e4ce8c _ZNKSt3__110__function12__value_funcIFvvEEclB6v15006Ev + 68\n90  RNTester                            0x0000000102e4ce3c _ZNKSt3__18functionIFvvEEclEv + 24\n91  RNTester                            0x000000010349d744 _ZZN8facebook5react8Instance13JSCallInvoker13scheduleAsyncEONSt3__18functionIFvvEEEENK3$_3clEPNS0_10JSExecutorE + 28\n92  RNTester                            0x000000010349d71c _ZNSt3__18__invokeB6v15006IRZN8facebook5react8Instance13JSCallInvoker13scheduleAsyncEONS_8functionIFvvEEEE3$_3JPNS2_10JSExecutorEEEEDTclclsr3stdE7declvalIT_EEspclsr3stdE7declvalIT0_EEEEOSD_DpOSE_ + 36\n93  RNTester                            0x000000010349d6c8 _ZNSt3__128__invoke_void_return_wrapperIvLb1EE6__callIJRZN8facebook5react8Instance13JSCallInvoker13scheduleAsyncEONS_8functionIFvvEEEE3$_3PNS4_10JSExecutorEEEEvDpOT_ + 32\n94  RNTester                            0x000000010349d69c _ZNSt3__110__function12__alloc_funcIZN8facebook5react8Instance13JSCallInvoker13scheduleAsyncEONS_8functionIFvvEEEE3$_3NS_9allocatorISA_EEFvPNS3_10JSExecutorEEEclB6v15006EOSE_ + 36\n95  RNTester                            0x000000010349c470 _ZNSt3__110__function6__funcIZN8facebook5react8Instance13JSCallInvoker13scheduleAsyncEONS_8functionIFvvEEEE3$_3NS_9allocatorISA_EEFvPNS3_10JSExecutorEEEclEOSE_ + 36\n96  RNTester                            0x00000001034c75dc _ZNKSt3__110__function12__value_funcIFvPN8facebook5react10JSExecutorEEEclB6v15006EOS5_ + 76\n97  RNTester                            0x00000001034c755c _ZNKSt3__18functionIFvPN8facebook5react10JSExecutorEEEclES4_ + 36\n98  RNTester                            0x00000001034c7528 _ZZN8facebook5react16NativeToJsBridge18runOnExecutorQueueENSt3__18functionIFvPNS0_10JSExecutorEEEEENK3$_8clEv + 92\n99  RNTester                            0x00000001034c74c0 _ZNSt3__18__invokeB6v15006IRZN8facebook5react16NativeToJsBridge18runOnExecutorQueueENS_8functionIFvPNS2_10JSExecutorEEEEE3$_8JEEEDTclclsr3stdE7declvalIT_EEspclsr3stdE7declvalIT0_EEEEOSB_DpOSC_ + 24\n100 RNTester                            0x00000001034c7478 _ZNSt3__128__invoke_void_return_wrapperIvLb1EE6__callIJRZN8facebook5react16NativeToJsBridge18runOnExecutorQueueENS_8functionIFvPNS4_10JSExecutorEEEEE3$_8EEEvDpOT_ + 24\n101 RNTester                            0x00000001034c7454 _ZNSt3__110__function12__alloc_funcIZN8facebook5react16NativeToJsBridge18runOnExecutorQueueENS_8functionIFvPNS3_10JSExecutorEEEEE3$_8NS_9allocatorISA_EEFvvEEclB6v15006Ev + 28\n102 RNTester                            0x00000001034c5fe8 _ZNSt3__110__function6__funcIZN8facebook5react16NativeToJsBridge18runOnExecutorQueueENS_8functionIFvPNS3_10JSExecutorEEEEE3$_8NS_9allocatorISA_EEFvvEEclEv + 28\n103 RNTester                            0x0000000102e4ce8c _ZNKSt3__110__function12__value_funcIFvvEEclB6v15006Ev + 68\n104 RNTester                            0x0000000102e4ce3c _ZNKSt3__18functionIFvvEEclEv + 24\n105 RNTester                            0x0000000102f68120 _ZN8facebook5react17tryAndReturnErrorERKNSt3__18functionIFvvEEE + 24\n106 RNTester                            0x0000000102f8b970 _ZN8facebook5react16RCTMessageThread7tryFuncERKNSt3__18functionIFvvEEE + 36\n107 RNTester                            0x0000000102f904b0 _ZZN8facebook5react16RCTMessageThread10runOnQueueEONSt3__18functionIFvvEEEENK3$_1clEv + 80\n108 RNTester                            0x0000000102f90454 _ZNSt3__18__invokeB6v15006IRZN8facebook5react16RCTMessageThread10runOnQueueEONS_8functionIFvvEEEE3$_1JEEEDTclclsr3stdE7declvalIT_EEspclsr3stdE7declvalIT0_EEEEOSA_DpOSB_ + 24\n109 RNTester                            0x0000000102f9040c _ZNSt3__128__invoke_void_return_wrapperIvLb1EE6__callIJRZN8facebook5react16RCTMessageThread10runOnQueueEONS_8functionIFvvEEEE3$_1EEEvDpOT_ + 24\n110 RNTester                            0x0000000102f903e8 _ZNSt3__110__function12__alloc_funcIZN8facebook5react16RCTMessageThread10runOnQueueEONS_8functionIFvvEEEE3$_1NS_9allocatorIS9_EES6_EclB6v15006Ev + 28\n111 RNTester                            0x0000000102f8f0f8 _ZNSt3__110__function6__funcIZN8facebook5react16RCTMessageThread10runOnQueueEONS_8functionIFvvEEEE3$_1NS_9allocatorIS9_EES6_EclEv + 28\n112 RNTester                            0x0000000102e4ce8c _ZNKSt3__110__function12__value_funcIFvvEEclB6v15006Ev + 68\n113 RNTester                            0x0000000102e4ce3c _ZNKSt3__18functionIFvvEEclEv + 24\n114 RNTester                            0x0000000102f8b740 ___ZN8facebook5react16RCTMessageThread8runAsyncENSt3__18functionIFvvEEE_block_invoke + 48\n115 CoreFoundation                      0x000000018039aa34 __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 20\n116 CoreFoundation                      0x000000018039a17c __CFRunLoopDoBlocks + 360\n117 CoreFoundation                      0x0000000180394f8c __CFRunLoopRun + 2336\n118 CoreFoundation                      0x0000000180394254 CFRunLoopRunSpecific + 584\n119 RNTester                            0x0000000102f42588 +[RCTCxxBridge runRunLoop] + 736\n120 Foundation                          0x0000000180bbede0 __NSThread__start__ + 704\n121 libsystem_pthread.dylib             0x00000001b18384e4 _pthread_start + 116\n122 libsystem_pthread.dylib             0x00000001b18336cc thread_start + 8\n"
  }
}
```

How I logged out the Errors:

```js
console.log('Error in JS:', JSON.stringify({
  name: e.name,
  message: e.message,
  stack: e.stack,
  ...e,
}, null, 2));
```

For to me unknown reason the `name`, `message` and `stack` is not printed when I directly stringify `e`.

Reviewed By: rshest

Differential Revision: D45182122

Pulled By: javache

fbshipit-source-id: 63e71c054b70816e3c021d69437805a82a7ef64e
  • Loading branch information
krystofwoldrich authored and jeongshin committed May 7, 2023
1 parent 6e5f263 commit 4dcf483
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 4 deletions.
5 changes: 5 additions & 0 deletions packages/react-native/ReactCommon/jsc/JSCRuntime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1240,6 +1240,11 @@ jsi::Function JSCRuntime::createFunctionFromHostFunction(
exceptionString += ex.what();
*exception = makeError(rt, exceptionString);
res = JSValueMakeUndefined(ctx);
} catch (const std::string &ex) {
std::string exceptionString("Exception in HostFunction: ");
exceptionString += ex;
*exception = makeError(rt, exceptionString);
res = JSValueMakeUndefined(ctx);
} catch (...) {
std::string exceptionString("Exception in HostFunction: <unknown>");
*exception = makeError(rt, exceptionString);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,53 @@ jsi::Value convertFromJMapToValue(JNIEnv *env, jsi::Runtime &rt, jobject arg) {
return jsi::valueFromDynamic(rt, result->cthis()->consume());
}

jsi::Value createJSRuntimeError(
jsi::Runtime &runtime,
const std::string &message) {
return runtime.global()
.getPropertyAsFunction(runtime, "Error")
.call(runtime, message);
}

/**
* Creates JSError with current JS runtime stack and Throwable stack trace.
*/
jsi::JSError convertThrowableToJSError(
jsi::Runtime &runtime,
jni::local_ref<jni::JThrowable> throwable) {
auto stackTrace = throwable->getStackTrace();

jsi::Array stackElements(runtime, stackTrace->size());
for (int i = 0; i < stackTrace->size(); ++i) {
auto frame = stackTrace->getElement(i);

jsi::Object frameObject(runtime);
frameObject.setProperty(runtime, "className", frame->getClassName());
frameObject.setProperty(runtime, "fileName", frame->getFileName());
frameObject.setProperty(runtime, "lineNumber", frame->getLineNumber());
frameObject.setProperty(runtime, "methodName", frame->getMethodName());
stackElements.setValueAtIndex(runtime, i, std::move(frameObject));
}

jsi::Object cause(runtime);
auto getName = throwable->getClass()
->getClass()
->getMethod<jni::local_ref<jni::JString>()>("getName");
auto getMessage =
throwable->getClass()->getMethod<jni::local_ref<jni::JString>()>(
"getMessage");
auto message = getMessage(throwable)->toStdString();
cause.setProperty(
runtime, "name", getName(throwable->getClass())->toStdString());
cause.setProperty(runtime, "message", message);
cause.setProperty(runtime, "stackElements", std::move(stackElements));

jsi::Value error =
createJSRuntimeError(runtime, "Exception in HostFunction: " + message);
error.asObject(runtime).setProperty(runtime, "cause", std::move(cause));
return {runtime, std::move(error)};
}

} // namespace

jsi::Value JavaTurboModule::invokeJavaMethod(
Expand Down Expand Up @@ -467,7 +514,9 @@ jsi::Value JavaTurboModule::invokeJavaMethod(
} else {
TMPL::asyncMethodCallFail(moduleName, methodName);
}
throw;
auto exception = std::current_exception();
auto throwable = jni::getJavaExceptionForCppException(exception);
throw convertThrowableToJSError(runtime, throwable);
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,30 @@ static int32_t getUniqueId()

namespace facebook::react {

static jsi::Value createJSRuntimeError(jsi::Runtime &runtime, const std::string &message)
{
return runtime.global().getPropertyAsFunction(runtime, "Error").call(runtime, message);
}

/**
* Creates JSError with current JS runtime and NSException stack trace.
*/
static jsi::JSError convertNSExceptionToJSError(jsi::Runtime &runtime, NSException *exception)
{
std::string reason = [exception.reason UTF8String];

jsi::Object cause(runtime);
cause.setProperty(runtime, "name", [exception.name UTF8String]);
cause.setProperty(runtime, "message", reason);
cause.setProperty(runtime, "stackSymbols", convertNSArrayToJSIArray(runtime, exception.callStackSymbols));
cause.setProperty(
runtime, "stackReturnAddresses", convertNSArrayToJSIArray(runtime, exception.callStackReturnAddresses));

jsi::Value error = createJSRuntimeError(runtime, "Exception in HostFunction: " + reason);
error.asObject(runtime).setProperty(runtime, "cause", std::move(cause));
return {runtime, std::move(error)};
}

jsi::Value ObjCTurboModule::createPromise(jsi::Runtime &runtime, std::string methodName, PromiseInvocationBlock invoke)
{
if (!invoke) {
Expand Down Expand Up @@ -376,9 +400,13 @@ static int32_t getUniqueId()
TurboModulePerfLogger::asyncMethodCallExecutionStart(moduleName, methodNameStr.c_str(), asyncCallCounter);
}

// TODO(T66699874) Should we guard this with a try/catch?
[inv invokeWithTarget:strongModule];
[retainedObjectsForInvocation removeAllObjects];
@try {
[inv invokeWithTarget:strongModule];
} @catch (NSException *exception) {
throw convertNSExceptionToJSError(runtime, exception);
} @finally {
[retainedObjectsForInvocation removeAllObjects];
}

if (!wasMethodSync) {
TurboModulePerfLogger::asyncMethodCallExecutionEnd(moduleName, methodNameStr.c_str(), asyncCallCounter);
Expand Down

0 comments on commit 4dcf483

Please sign in to comment.