mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-04-24 04:16:00 +08:00
Fix error handling for nested exceptions
Reviewed By: mhorowitz Differential Revision: D4551110 fbshipit-source-id: e593c1ef0dea27e95a387bcde6250aeb22d2e9cc
This commit is contained in:
committed by
Facebook Github Bot
parent
bbe0c45c19
commit
8987d86718
@@ -17,3 +17,10 @@ id RCTConvertFollyDynamic(const folly::dynamic &dyn);
|
||||
+ (folly::dynamic)folly_dynamic:(id)json;
|
||||
|
||||
@end
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
NSError *tryAndReturnError(const std::function<void()>& func);
|
||||
|
||||
} }
|
||||
|
||||
@@ -10,7 +10,11 @@
|
||||
#import "RCTCxxUtils.h"
|
||||
|
||||
#import <React/RCTFollyConvert.h>
|
||||
#import <React/RCTUtils.h>
|
||||
|
||||
#include <jschelpers/Value.h>
|
||||
|
||||
using namespace facebook::react;
|
||||
using namespace react::CxxUtils;
|
||||
|
||||
id RCTConvertFollyDynamic(const folly::dynamic &dyn) {
|
||||
@@ -33,3 +37,58 @@ id RCTConvertFollyDynamic(const folly::dynamic &dyn) {
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
static NSError *errorWithException(const std::exception& e)
|
||||
{
|
||||
NSString *msg = @(e.what());
|
||||
NSMutableDictionary *errorInfo = [NSMutableDictionary dictionary];
|
||||
|
||||
const JSException *jsException = dynamic_cast<const JSException*>(&e);
|
||||
if (jsException) {
|
||||
errorInfo[RCTJSRawStackTraceKey] = @(jsException->getStack().c_str());
|
||||
msg = [@"Unhandled JS Exception: " stringByAppendingString:msg];
|
||||
}
|
||||
|
||||
NSError *nestedError;
|
||||
try {
|
||||
std::rethrow_if_nested(e);
|
||||
} catch(const std::exception& e) {
|
||||
nestedError = errorWithException(e);
|
||||
} catch(...) {}
|
||||
|
||||
if (nestedError) {
|
||||
msg = [NSString stringWithFormat:@"%@\n\n%@", msg, [nestedError localizedDescription]];
|
||||
}
|
||||
|
||||
errorInfo[NSLocalizedDescriptionKey] = msg;
|
||||
return [NSError errorWithDomain:RCTErrorDomain code:1 userInfo:errorInfo];
|
||||
}
|
||||
|
||||
NSError *tryAndReturnError(const std::function<void()>& func) {
|
||||
try {
|
||||
@try {
|
||||
func();
|
||||
return nil;
|
||||
}
|
||||
@catch (NSException *exception) {
|
||||
NSString *message =
|
||||
[NSString stringWithFormat:@"Exception '%@' was thrown from JS thread", exception];
|
||||
return RCTErrorWithMessage(message);
|
||||
}
|
||||
@catch (id exception) {
|
||||
// This will catch any other ObjC exception, but no C++ exceptions
|
||||
return RCTErrorWithMessage(@"non-std ObjC Exception");
|
||||
}
|
||||
} catch (const std::exception &ex) {
|
||||
return errorWithException(ex);
|
||||
} catch (...) {
|
||||
// On a 64-bit platform, this would catch ObjC exceptions, too, but not on
|
||||
// 32-bit platforms, so we catch those with id exceptions above.
|
||||
return RCTErrorWithMessage(@"non-std C++ exception");
|
||||
}
|
||||
}
|
||||
|
||||
} }
|
||||
|
||||
Reference in New Issue
Block a user