|
7 | 7 |
|
8 | 8 | package com.facebook.react.runtime; |
9 | 9 |
|
| 10 | +import static com.facebook.react.util.JSStackTrace.COLUMN_KEY; |
| 11 | +import static com.facebook.react.util.JSStackTrace.FILE_KEY; |
| 12 | +import static com.facebook.react.util.JSStackTrace.LINE_NUMBER_KEY; |
| 13 | +import static com.facebook.react.util.JSStackTrace.METHOD_NAME_KEY; |
| 14 | + |
10 | 15 | import android.content.res.AssetManager; |
11 | 16 | import android.view.View; |
12 | 17 | import com.facebook.common.logging.FLog; |
| 18 | +import com.facebook.fbreact.specs.NativeExceptionsManagerSpec; |
| 19 | +import com.facebook.infer.annotation.Assertions; |
13 | 20 | import com.facebook.infer.annotation.Nullsafe; |
14 | 21 | import com.facebook.infer.annotation.ThreadConfined; |
15 | 22 | import com.facebook.infer.annotation.ThreadSafe; |
|
21 | 28 | import com.facebook.react.bridge.Arguments; |
22 | 29 | import com.facebook.react.bridge.JSBundleLoader; |
23 | 30 | import com.facebook.react.bridge.JSBundleLoaderDelegate; |
| 31 | +import com.facebook.react.bridge.JavaOnlyArray; |
| 32 | +import com.facebook.react.bridge.JavaOnlyMap; |
24 | 33 | import com.facebook.react.bridge.JavaScriptContextHolder; |
25 | 34 | import com.facebook.react.bridge.NativeArray; |
26 | 35 | import com.facebook.react.bridge.NativeMap; |
27 | 36 | import com.facebook.react.bridge.NativeModule; |
28 | 37 | import com.facebook.react.bridge.ReactNoCrashSoftException; |
29 | 38 | import com.facebook.react.bridge.ReactSoftExceptionLogger; |
| 39 | +import com.facebook.react.bridge.ReadableMap; |
30 | 40 | import com.facebook.react.bridge.RuntimeExecutor; |
31 | 41 | import com.facebook.react.bridge.RuntimeScheduler; |
32 | 42 | import com.facebook.react.bridge.queue.MessageQueueThread; |
@@ -110,7 +120,6 @@ final class ReactInstance { |
110 | 120 | ComponentFactory componentFactory, |
111 | 121 | DevSupportManager devSupportManager, |
112 | 122 | QueueThreadExceptionHandler exceptionHandler, |
113 | | - ReactJsExceptionHandler reactExceptionManager, |
114 | 123 | boolean useDevSupport, |
115 | 124 | @Nullable ReactHostInspectorTarget reactHostInspectorTarget) { |
116 | 125 | mBridgelessReactContext = bridgelessReactContext; |
@@ -154,14 +163,15 @@ final class ReactInstance { |
154 | 163 | // Notify JS if profiling is enabled |
155 | 164 | boolean isProfiling = |
156 | 165 | Systrace.isTracing(Systrace.TRACE_TAG_REACT_APPS | Systrace.TRACE_TAG_REACT_JS_VM_CALLS); |
| 166 | + |
157 | 167 | mHybridData = |
158 | 168 | initHybrid( |
159 | 169 | jsRuntimeFactory, |
160 | 170 | jsMessageQueueThread, |
161 | 171 | nativeModulesMessageQueueThread, |
162 | 172 | mJavaTimerManager, |
163 | 173 | jsTimerExecutor, |
164 | | - reactExceptionManager, |
| 174 | + new ReactJsExceptionHandlerImpl(nativeModulesMessageQueueThread), |
165 | 175 | bindingsInstaller, |
166 | 176 | isProfiling, |
167 | 177 | reactHostInspectorTarget); |
@@ -313,6 +323,44 @@ public ReactQueueConfiguration getReactQueueConfiguration() { |
313 | 323 | return mQueueConfiguration; |
314 | 324 | } |
315 | 325 |
|
| 326 | + private class ReactJsExceptionHandlerImpl implements ReactJsExceptionHandler { |
| 327 | + private final MessageQueueThread mNativemodulesmessagequeuethread; |
| 328 | + |
| 329 | + ReactJsExceptionHandlerImpl(MessageQueueThread nativeModulesMessageQueueThread) { |
| 330 | + this.mNativemodulesmessagequeuethread = nativeModulesMessageQueueThread; |
| 331 | + } |
| 332 | + |
| 333 | + @Override |
| 334 | + public void reportJsException(ParsedError error) { |
| 335 | + List<ReactJsExceptionHandler.ParsedError.StackFrame> frames = error.getFrames(); |
| 336 | + List<ReadableMap> readableMapList = new ArrayList<>(); |
| 337 | + for (ReactJsExceptionHandler.ParsedError.StackFrame frame : frames) { |
| 338 | + JavaOnlyMap map = new JavaOnlyMap(); |
| 339 | + map.putDouble(COLUMN_KEY, frame.getColumnNumber()); |
| 340 | + map.putDouble(LINE_NUMBER_KEY, frame.getLineNumber()); |
| 341 | + map.putString(FILE_KEY, (String) frame.getFileName()); |
| 342 | + map.putString(METHOD_NAME_KEY, (String) frame.getMethodName()); |
| 343 | + readableMapList.add(map); |
| 344 | + } |
| 345 | + |
| 346 | + JavaOnlyMap data = new JavaOnlyMap(); |
| 347 | + data.putString("message", error.getMessage()); |
| 348 | + data.putArray("stack", JavaOnlyArray.from(readableMapList)); |
| 349 | + data.putInt("id", error.getExceptionId()); |
| 350 | + data.putBoolean("isFatal", error.isFatal()); |
| 351 | + |
| 352 | + // Simulate async native module method call |
| 353 | + mNativemodulesmessagequeuethread.runOnQueue( |
| 354 | + () -> { |
| 355 | + NativeExceptionsManagerSpec exceptionsManager = |
| 356 | + (NativeExceptionsManagerSpec) |
| 357 | + Assertions.assertNotNull( |
| 358 | + mTurboModuleManager.getModule(NativeExceptionsManagerSpec.NAME)); |
| 359 | + exceptionsManager.reportException(data); |
| 360 | + }); |
| 361 | + } |
| 362 | + } |
| 363 | + |
316 | 364 | public void loadJSBundle(JSBundleLoader bundleLoader) { |
317 | 365 | // Load the JS bundle |
318 | 366 | Systrace.beginSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "ReactInstance.loadJSBundle"); |
|
0 commit comments