Red box c++ exceptions thrown while executing sync hooks
Summary: Also adds support for creating JS Error objects. When we clean up the way global functions are installed on JSC, we'll be able to use this pattern to auto-catch all c++ exceptions at this level. Reviewed By: lexs Differential Revision: D3276663 fbshipit-source-id: bf3561690013019a25e2be5a4d1b69ba9e002c72
This commit is contained in:
parent
ca1caf2713
commit
6ec5b953cb
|
@ -628,14 +628,19 @@ JSValueRef JSCExecutor::nativeCallSyncHook(
|
||||||
return JSValueMakeUndefined(ctx);
|
return JSValueMakeUndefined(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
MethodCallResult result = executor->m_bridge->callSerializableNativeHook(
|
try {
|
||||||
moduleId,
|
MethodCallResult result = executor->m_bridge->callSerializableNativeHook(
|
||||||
methodId,
|
moduleId,
|
||||||
argsJson);
|
methodId,
|
||||||
if (result.isUndefined) {
|
argsJson);
|
||||||
|
if (result.isUndefined) {
|
||||||
|
return JSValueMakeUndefined(ctx);
|
||||||
|
}
|
||||||
|
return Value::fromJSON(ctx, String(folly::toJson(result.result).c_str()));
|
||||||
|
} catch (...) {
|
||||||
|
*exception = translatePendingCppExceptionToJSError(ctx, "nativeCallSyncHook");
|
||||||
return JSValueMakeUndefined(ctx);
|
return JSValueMakeUndefined(ctx);
|
||||||
}
|
}
|
||||||
return Value::fromJSON(ctx, String(folly::toJson(result.result).c_str()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSValueRef nativeInjectHMRUpdate(
|
static JSValueRef nativeInjectHMRUpdate(
|
||||||
|
|
|
@ -52,4 +52,32 @@ JSValueRef evaluateScript(JSContextRef context, JSStringRef script, JSStringRef
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JSValueRef makeJSError(JSContextRef ctx, const char *error) {
|
||||||
|
JSValueRef nestedException = nullptr;
|
||||||
|
JSValueRef args[] = { Value(ctx, String(error)) };
|
||||||
|
JSObjectRef errorObj = JSObjectMakeError(ctx, 1, args, &nestedException);
|
||||||
|
if (nestedException != nullptr) {
|
||||||
|
return std::move(args[0]);
|
||||||
|
}
|
||||||
|
return errorObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
JSValueRef translatePendingCppExceptionToJSError(JSContextRef ctx, const char *exceptionLocation) {
|
||||||
|
std::ostringstream msg;
|
||||||
|
try {
|
||||||
|
throw;
|
||||||
|
} catch (const std::bad_alloc& ex) {
|
||||||
|
throw; // We probably shouldn't try to handle this in JS
|
||||||
|
} catch (const std::exception& ex) {
|
||||||
|
msg << "C++ Exception in '" << exceptionLocation << "': " << ex.what();
|
||||||
|
return makeJSError(ctx, msg.str().c_str());
|
||||||
|
} catch (const char* ex) {
|
||||||
|
msg << "C++ Exception (thrown as a char*) in '" << exceptionLocation << "': " << ex;
|
||||||
|
return makeJSError(ctx, msg.str().c_str());
|
||||||
|
} catch (...) {
|
||||||
|
msg << "Unknown C++ Exception in '" << exceptionLocation << "'";
|
||||||
|
return makeJSError(ctx, msg.str().c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} }
|
} }
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include "Value.h"
|
||||||
|
|
||||||
namespace facebook {
|
namespace facebook {
|
||||||
namespace react {
|
namespace react {
|
||||||
|
|
||||||
|
@ -43,4 +45,8 @@ JSValueRef evaluateScript(
|
||||||
JSStringRef script,
|
JSStringRef script,
|
||||||
JSStringRef sourceURL);
|
JSStringRef sourceURL);
|
||||||
|
|
||||||
|
JSValueRef makeJSError(JSContextRef ctx, const char *error);
|
||||||
|
|
||||||
|
JSValueRef translatePendingCppExceptionToJSError(JSContextRef ctx, const char *exceptionLocation);
|
||||||
|
|
||||||
} }
|
} }
|
||||||
|
|
|
@ -13,6 +13,12 @@ Value::Value(JSContextRef context, JSValueRef value) :
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Value::Value(JSContextRef context, JSStringRef str) :
|
||||||
|
m_context(context),
|
||||||
|
m_value(JSValueMakeString(context, str))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
Value::Value(Value&& other) :
|
Value::Value(Value&& other) :
|
||||||
m_context(other.m_context),
|
m_context(other.m_context),
|
||||||
m_value(other.m_value)
|
m_value(other.m_value)
|
||||||
|
|
|
@ -171,6 +171,7 @@ private:
|
||||||
class Value : public noncopyable {
|
class Value : public noncopyable {
|
||||||
public:
|
public:
|
||||||
Value(JSContextRef context, JSValueRef value);
|
Value(JSContextRef context, JSValueRef value);
|
||||||
|
Value(JSContextRef context, JSStringRef value);
|
||||||
Value(Value&&);
|
Value(Value&&);
|
||||||
|
|
||||||
operator JSValueRef() const {
|
operator JSValueRef() const {
|
||||||
|
|
Loading…
Reference in New Issue