|
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