Skip to content

Commit 1b994f9

Browse files
sherginfacebook-github-bot
authored andcommittedSep 8, 2020
Proxing NSException stack trace to NSError object
Summary: When we catch an Objective-C exception and convert it to NSError we need to somehow represent the call stack from NSException instance in NSError instance. For now, we just attach the stack trace to `message` field. The next step would be to figure out how to pass the Objective-C stack trace to error reporting infra to help it to display the stack trace nicely in the web interface. Changelog: [Internal] Fabric-specific internal change. Reviewed By: sammy-SC Differential Revision: D23557600 fbshipit-source-id: a080c2e186e719e42dcfc01bb12f5811e3c5b2e6
1 parent aaeffdb commit 1b994f9

File tree

5 files changed

+20
-2
lines changed

5 files changed

+20
-2
lines changed
 

‎React/Base/RCTAssert.h

+5
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,11 @@ RCT_EXTERN NSString *const RCTJSStackTraceKey;
6464
*/
6565
RCT_EXTERN NSString *const RCTJSRawStackTraceKey;
6666

67+
/**
68+
* Objective-C stack trace string provided as part of an NSError's userInfo
69+
*/
70+
RCT_EXTERN NSString *const RCTObjCStackTraceKey;
71+
6772
/**
6873
* Name of fatal exceptions generated by RCTFatal
6974
*/

‎React/Base/RCTAssert.m

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
NSString *const RCTErrorDomain = @"RCTErrorDomain";
1212
NSString *const RCTJSStackTraceKey = @"RCTJSStackTraceKey";
1313
NSString *const RCTJSRawStackTraceKey = @"RCTJSRawStackTraceKey";
14+
NSString *const RCTObjCStackTraceKey = @"RCTObjCStackTraceKey";
1415
NSString *const RCTFatalExceptionName = @"RCTFatalException";
1516
NSString *const RCTUntruncatedMessageKey = @"RCTUntruncatedMessageKey";
1617

‎React/Base/RCTUtils.h

+3
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,9 @@ RCT_EXTERN BOOL RCTForceTouchAvailable(void);
9898
// Create an NSError in the RCTErrorDomain
9999
RCT_EXTERN NSError *RCTErrorWithMessage(NSString *message);
100100

101+
// Creates an NSError from given an NSException
102+
RCT_EXTERN NSError *RCTErrorWithNSException(NSException *exception);
103+
101104
// Convert nil values to NSNull, and vice-versa
102105
#define RCTNullIfNil(value) ((value) ?: (id)kCFNull)
103106
#define RCTNilIfNull(value) \

‎React/Base/RCTUtils.m

+10
Original file line numberDiff line numberDiff line change
@@ -581,6 +581,16 @@ BOOL RCTForceTouchAvailable(void)
581581
return [[NSError alloc] initWithDomain:RCTErrorDomain code:0 userInfo:errorInfo];
582582
}
583583

584+
NSError *RCTErrorWithNSException(NSException *exception)
585+
{
586+
NSString *message = [NSString stringWithFormat:@"NSException: %@; trace: %@.",
587+
exception,
588+
[[exception callStackSymbols] componentsJoinedByString:@";"]];
589+
NSDictionary<NSString *, id> *errorInfo =
590+
@{NSLocalizedDescriptionKey : message, RCTObjCStackTraceKey : [exception callStackSymbols]};
591+
return [[NSError alloc] initWithDomain:RCTErrorDomain code:0 userInfo:errorInfo];
592+
}
593+
584594
double RCTZeroIfNaN(double value)
585595
{
586596
return isnan(value) || isinf(value) ? 0 : value;

‎React/CxxModule/RCTCxxUtils.mm

+1-2
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,7 @@
7474
func();
7575
return nil;
7676
} @catch (NSException *exception) {
77-
NSString *message = [NSString stringWithFormat:@"Exception '%@' was thrown from JS thread", exception];
78-
return RCTErrorWithMessage(message);
77+
return RCTErrorWithNSException(exception);
7978
} @catch (id exception) {
8079
// This will catch any other ObjC exception, but no C++ exceptions
8180
return RCTErrorWithMessage(@"non-std ObjC Exception");

0 commit comments

Comments
 (0)
Please sign in to comment.