Skip to content

Commit d6c879e

Browse files
sota000facebook-github-bot
authored andcommitted
Show RedBox for C++ errors
Summary: This diff is hooking up cxx error with redbox. Before this diff, cxx errors were only shown in log and there was no visible user feedback. Changelog: [Android] [Added] - Show Redbox for C++ errors. Reviewed By: JoshuaGross Differential Revision: D30421355 fbshipit-source-id: ad473337ba301feb08ba31ee8d82ebaa771ecaeb
1 parent 4a96216 commit d6c879e

File tree

5 files changed

+104
-0
lines changed

5 files changed

+104
-0
lines changed

ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java

+20
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
import com.facebook.react.bridge.ProxyJavaScriptExecutor;
6666
import com.facebook.react.bridge.ReactApplicationContext;
6767
import com.facebook.react.bridge.ReactContext;
68+
import com.facebook.react.bridge.ReactCxxErrorHandler;
6869
import com.facebook.react.bridge.ReactMarker;
6970
import com.facebook.react.bridge.ReactMarkerConstants;
7071
import com.facebook.react.bridge.ReactNoCrashSoftException;
@@ -107,6 +108,7 @@
107108
import com.facebook.soloader.SoLoader;
108109
import com.facebook.systrace.Systrace;
109110
import com.facebook.systrace.SystraceMessage;
111+
import java.lang.reflect.Method;
110112
import java.util.ArrayList;
111113
import java.util.Collection;
112114
import java.util.Collections;
@@ -291,6 +293,8 @@ public void invokeDefaultOnBackPressed() {
291293
if (mUseDeveloperSupport) {
292294
mDevSupportManager.startInspector();
293295
}
296+
297+
registerCxxErrorHandlerFunc();
294298
}
295299

296300
private ReactInstanceDevHelper createDevHelperInterface() {
@@ -364,6 +368,22 @@ public List<ReactPackage> getPackages() {
364368
return new ArrayList<>(mPackages);
365369
}
366370

371+
public void handleCxxError(Exception e) {
372+
mDevSupportManager.handleException(e);
373+
}
374+
375+
public void registerCxxErrorHandlerFunc() {
376+
Class[] parameterTypes = new Class[1];
377+
parameterTypes[0] = Exception.class;
378+
Method handleCxxErrorFunc = null;
379+
try {
380+
handleCxxErrorFunc = ReactInstanceManager.class.getMethod("handleCxxError", parameterTypes);
381+
} catch (NoSuchMethodException e) {
382+
FLog.e("ReactInstanceHolder", "Failed to set cxx error hanlder function", e);
383+
}
384+
ReactCxxErrorHandler.setHandleErrorFunc(this, handleCxxErrorFunc);
385+
}
386+
367387
static void initializeSoLoaderIfNecessary(Context applicationContext) {
368388
// Call SoLoader.initialize here, this is required for apps that does not use exopackage and
369389
// does not use SoLoader for loading other native code except from the one used by React Native
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright (c) Facebook, Inc. and its affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
package com.facebook.react.bridge;
9+
10+
import com.facebook.common.logging.FLog;
11+
import com.facebook.proguard.annotations.DoNotStrip;
12+
import java.lang.reflect.Method;
13+
14+
@DoNotStrip
15+
public class ReactCxxErrorHandler {
16+
17+
private static Method mHandleErrorFunc;
18+
private static Object mObject;
19+
20+
@DoNotStrip
21+
public static void setHandleErrorFunc(Object object, Method handleErrorFunc) {
22+
mObject = object;
23+
mHandleErrorFunc = handleErrorFunc;
24+
}
25+
26+
@DoNotStrip
27+
// For use from within the C++ JReactCxxErrorHandler
28+
private static void handleError(final String message) {
29+
if (mHandleErrorFunc != null) {
30+
try {
31+
Object[] parameters = new Object[1];
32+
parameters[0] = new Exception(message);
33+
mHandleErrorFunc.invoke(mObject, parameters);
34+
} catch (Exception e) {
35+
FLog.e("ReactCxxErrorHandler", "Failed to invole error hanlder function", e);
36+
}
37+
}
38+
}
39+
}

ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232

3333
#include "CxxModuleWrapper.h"
3434
#include "JNativeRunnable.h"
35+
#include "JReactCxxErrorHandler.h"
3536
#include "JReactSoftExceptionLogger.h"
3637
#include "JavaScriptExecutorHolder.h"
3738
#include "JniJSModulesUnbundle.h"
@@ -155,6 +156,7 @@ void log(ReactNativeLogLevel level, const char *message) {
155156
break;
156157
case ReactNativeLogLevelError:
157158
LOG(ERROR) << message;
159+
JReactCxxErrorHandler::handleError(message);
158160
break;
159161
case ReactNativeLogLevelFatal:
160162
LOG(FATAL) << message;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/*
2+
* Copyright (c) Facebook, Inc. and its affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
#include "JReactCxxErrorHandler.h"
9+
10+
using namespace facebook::react;
11+
12+
void JReactCxxErrorHandler::handleError(std::string message) {
13+
static const auto handleError =
14+
javaClassStatic()->getStaticMethod<void(std::string message)>(
15+
"handleError");
16+
17+
return handleError(javaClassStatic(), message);
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Copyright (c) Facebook, Inc. and its affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
#pragma once
9+
10+
#include <fbjni/fbjni.h>
11+
#include <string>
12+
13+
namespace facebook {
14+
namespace react {
15+
16+
class JReactCxxErrorHandler : public jni::JavaClass<JReactCxxErrorHandler> {
17+
public:
18+
static constexpr const char *kJavaDescriptor =
19+
"Lcom/facebook/react/bridge/ReactCxxErrorHandler;";
20+
21+
static void handleError(std::string message);
22+
};
23+
24+
} // namespace react
25+
} // namespace facebook

0 commit comments

Comments
 (0)