From 9647c5a25724ddd259a4febe7e7f26c058ce3fac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Oghin=C4=83?= Date: Fri, 6 Nov 2015 11:42:24 -0800 Subject: [PATCH] show script eval errors in redbox Differential Revision: D2624801 fb-gh-sync-id: 48741a8caf029415753a4c616a07f18d3660e6fb --- .../facebook/react/bridge/CatalystInstance.java | 6 +++++- .../react/bridge/JSExecutionException.java | 17 +++++++++++++++++ ReactAndroid/src/main/jni/react/JSCExecutor.cpp | 14 ++++++++++++++ ReactAndroid/src/main/jni/react/jni/OnLoad.cpp | 6 ++++++ 4 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 ReactAndroid/src/main/java/com/facebook/react/bridge/JSExecutionException.java diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstance.java b/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstance.java index 80fb5c2ed..96682eace 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstance.java +++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstance.java @@ -134,7 +134,11 @@ public class CatalystInstance { incrementPendingJSCalls(); - mJSBundleLoader.loadScript(mBridge); + try { + mJSBundleLoader.loadScript(mBridge); + } catch (JSExecutionException e) { + mNativeModuleCallExceptionHandler.handleException(e); + } initLatch.countDown(); } diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/JSExecutionException.java b/ReactAndroid/src/main/java/com/facebook/react/bridge/JSExecutionException.java new file mode 100644 index 000000000..96e8f1544 --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/JSExecutionException.java @@ -0,0 +1,17 @@ +// Copyright 2004-present Facebook. All Rights Reserved. + +package com.facebook.react.bridge; + +import com.facebook.proguard.annotations.DoNotStrip; + +/** + * Exception thrown when there is an error evaluating JS, e.g. a syntax error. + */ +@DoNotStrip +public class JSExecutionException extends RuntimeException { + + @DoNotStrip + public JSExecutionException(String detailMessage) { + super(detailMessage); + } +} diff --git a/ReactAndroid/src/main/jni/react/JSCExecutor.cpp b/ReactAndroid/src/main/jni/react/JSCExecutor.cpp index e86c4035f..ca7afa29a 100644 --- a/ReactAndroid/src/main/jni/react/JSCExecutor.cpp +++ b/ReactAndroid/src/main/jni/react/JSCExecutor.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include "Value.h" #ifdef WITH_JSC_EXTRA_TRACING @@ -24,6 +25,8 @@ using fbsystrace::FbSystraceSection; // Add native performance markers support #include +using namespace facebook::jni; + namespace facebook { namespace react { @@ -53,6 +56,17 @@ static JSValueRef evaluateScriptWithJSC( JSValueProtect(ctx, exn); std::string exceptionText = Value(ctx, exn).toString().str(); FBLOGE("Got JS Exception: %s", exceptionText.c_str()); + auto line = Value(ctx, JSObjectGetProperty(ctx, + JSValueToObject(ctx, exn, nullptr), + JSStringCreateWithUTF8CString("line"), nullptr + )); + std::ostringstream lineInfo; + if (line != nullptr && line.isNumber()) { + lineInfo << " (line " << line.asInteger() << " in the generated bundle)"; + } else { + lineInfo << " (no line info)"; + } + throwNewJavaException("com/facebook/react/bridge/JSExecutionException", (exceptionText + lineInfo.str()).c_str()); } return result; } diff --git a/ReactAndroid/src/main/jni/react/jni/OnLoad.cpp b/ReactAndroid/src/main/jni/react/jni/OnLoad.cpp index 885ddc1e1..bc35feeb2 100644 --- a/ReactAndroid/src/main/jni/react/jni/OnLoad.cpp +++ b/ReactAndroid/src/main/jni/react/jni/OnLoad.cpp @@ -648,6 +648,9 @@ static void loadScriptFromAssets(JNIEnv* env, jobject obj, jobject assetManager, env->CallStaticVoidMethod(markerClass, gLogMarkerMethod, env->NewStringUTF("loadScriptFromAssets_read")); executeApplicationScript(bridge, script, assetNameStr); + if (env->ExceptionCheck()) { + return; + } env->CallStaticVoidMethod(markerClass, gLogMarkerMethod, env->NewStringUTF("loadScriptFromAssets_done")); } @@ -666,6 +669,9 @@ static void loadScriptFromFile(JNIEnv* env, jobject obj, jstring fileName, jstri #endif env->CallStaticVoidMethod(markerClass, gLogMarkerMethod, env->NewStringUTF("loadScriptFromFile_read")); executeApplicationScript(bridge, script, jni::fromJString(env, sourceURL)); + if (env->ExceptionCheck()) { + return; + } env->CallStaticVoidMethod(markerClass, gLogMarkerMethod, env->NewStringUTF("loadScriptFromFile_exec")); }