Skip to content

Commit

Permalink
Show RedBox for C++ errors
Browse files Browse the repository at this point in the history
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
  • Loading branch information
sota000 authored and facebook-github-bot committed Aug 26, 2021
1 parent 4a96216 commit d6c879e
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
import com.facebook.react.bridge.ProxyJavaScriptExecutor;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactCxxErrorHandler;
import com.facebook.react.bridge.ReactMarker;
import com.facebook.react.bridge.ReactMarkerConstants;
import com.facebook.react.bridge.ReactNoCrashSoftException;
Expand Down Expand Up @@ -107,6 +108,7 @@
import com.facebook.soloader.SoLoader;
import com.facebook.systrace.Systrace;
import com.facebook.systrace.SystraceMessage;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
Expand Down Expand Up @@ -291,6 +293,8 @@ public void invokeDefaultOnBackPressed() {
if (mUseDeveloperSupport) {
mDevSupportManager.startInspector();
}

registerCxxErrorHandlerFunc();
}

private ReactInstanceDevHelper createDevHelperInterface() {
Expand Down Expand Up @@ -364,6 +368,22 @@ public List<ReactPackage> getPackages() {
return new ArrayList<>(mPackages);
}

public void handleCxxError(Exception e) {
mDevSupportManager.handleException(e);
}

public void registerCxxErrorHandlerFunc() {
Class[] parameterTypes = new Class[1];
parameterTypes[0] = Exception.class;
Method handleCxxErrorFunc = null;
try {
handleCxxErrorFunc = ReactInstanceManager.class.getMethod("handleCxxError", parameterTypes);
} catch (NoSuchMethodException e) {
FLog.e("ReactInstanceHolder", "Failed to set cxx error hanlder function", e);
}
ReactCxxErrorHandler.setHandleErrorFunc(this, handleCxxErrorFunc);
}

static void initializeSoLoaderIfNecessary(Context applicationContext) {
// Call SoLoader.initialize here, this is required for apps that does not use exopackage and
// does not use SoLoader for loading other native code except from the one used by React Native
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

package com.facebook.react.bridge;

import com.facebook.common.logging.FLog;
import com.facebook.proguard.annotations.DoNotStrip;
import java.lang.reflect.Method;

@DoNotStrip
public class ReactCxxErrorHandler {

private static Method mHandleErrorFunc;
private static Object mObject;

@DoNotStrip
public static void setHandleErrorFunc(Object object, Method handleErrorFunc) {
mObject = object;
mHandleErrorFunc = handleErrorFunc;
}

@DoNotStrip
// For use from within the C++ JReactCxxErrorHandler
private static void handleError(final String message) {
if (mHandleErrorFunc != null) {
try {
Object[] parameters = new Object[1];
parameters[0] = new Exception(message);
mHandleErrorFunc.invoke(mObject, parameters);
} catch (Exception e) {
FLog.e("ReactCxxErrorHandler", "Failed to invole error hanlder function", e);
}
}
}
}
2 changes: 2 additions & 0 deletions ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@

#include "CxxModuleWrapper.h"
#include "JNativeRunnable.h"
#include "JReactCxxErrorHandler.h"
#include "JReactSoftExceptionLogger.h"
#include "JavaScriptExecutorHolder.h"
#include "JniJSModulesUnbundle.h"
Expand Down Expand Up @@ -155,6 +156,7 @@ void log(ReactNativeLogLevel level, const char *message) {
break;
case ReactNativeLogLevelError:
LOG(ERROR) << message;
JReactCxxErrorHandler::handleError(message);
break;
case ReactNativeLogLevelFatal:
LOG(FATAL) << message;
Expand Down
18 changes: 18 additions & 0 deletions ReactAndroid/src/main/jni/react/jni/JReactCxxErrorHandler.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

#include "JReactCxxErrorHandler.h"

using namespace facebook::react;

void JReactCxxErrorHandler::handleError(std::string message) {
static const auto handleError =
javaClassStatic()->getStaticMethod<void(std::string message)>(
"handleError");

return handleError(javaClassStatic(), message);
}
25 changes: 25 additions & 0 deletions ReactAndroid/src/main/jni/react/jni/JReactCxxErrorHandler.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

#pragma once

#include <fbjni/fbjni.h>
#include <string>

namespace facebook {
namespace react {

class JReactCxxErrorHandler : public jni::JavaClass<JReactCxxErrorHandler> {
public:
static constexpr const char *kJavaDescriptor =
"Lcom/facebook/react/bridge/ReactCxxErrorHandler;";

static void handleError(std::string message);
};

} // namespace react
} // namespace facebook

0 comments on commit d6c879e

Please sign in to comment.