Skip to content

Commit a65ae8e

Browse files
GijsWeteringsfacebook-github-bot
authored andcommitted
Attach js_extra_data to JS errors on iOS
Summary: Changelog: [iOS][Fixed] - Expose the extraData dict attached to JavaScript errors to the native ExceptionManager on iOS, similar to Android Attaching the `extraData` dict to JavaScript crash reports is something that was done for Android only in 2019 (D16133080 (3a825c0)), and somehow we never really got around to adding it in iOS. This diff finally adds the capability to iOS as well. `extraData` can be used to attach various bits of data to a crash report for better debugging and categorization. As with the Android implementation, `extraData` is not attached if the `reportException` API is not used. Reviewed By: dmitryrykun Differential Revision: D35743658 fbshipit-source-id: de4060cb6e514db1d85907441a8962f98e9b8392
1 parent 4f855c8 commit a65ae8e

File tree

4 files changed

+31
-11
lines changed

4 files changed

+31
-11
lines changed

React/Base/RCTAssert.h

+5
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,11 @@ RCT_EXTERN NSString *const RCTObjCStackTraceKey;
7474
*/
7575
RCT_EXTERN NSString *const RCTFatalExceptionName;
7676

77+
/**
78+
* Stringified JSON object containing extra data to attach to the error from JavaScript.
79+
*/
80+
RCT_EXTERN NSString *const RCTJSExtraDataKey;
81+
7782
/**
7883
* A block signature to be used for custom assertion handling.
7984
*/

React/Base/RCTAssert.m

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
NSString *const RCTObjCStackTraceKey = @"RCTObjCStackTraceKey";
1515
NSString *const RCTFatalExceptionName = @"RCTFatalException";
1616
NSString *const RCTUntruncatedMessageKey = @"RCTUntruncatedMessageKey";
17+
NSString *const RCTJSExtraDataKey = @"RCTJSExtraDataKey";
1718

1819
static NSString *const RCTAssertFunctionStack = @"RCTAssertFunctionStack";
1920

React/CoreModules/RCTExceptionsManager.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,12 @@ NS_ASSUME_NONNULL_BEGIN
1515

1616
- (void)handleSoftJSExceptionWithMessage:(nullable NSString *)message
1717
stack:(nullable NSArray *)stack
18-
exceptionId:(NSNumber *)exceptionId;
18+
exceptionId:(NSNumber *)exceptionId
19+
extraDataAsJSON:(nullable NSString *)extraDataAsJSON;
1920
- (void)handleFatalJSExceptionWithMessage:(nullable NSString *)message
2021
stack:(nullable NSArray *)stack
21-
exceptionId:(NSNumber *)exceptionId;
22+
exceptionId:(NSNumber *)exceptionId
23+
extraDataAsJSON:(nullable NSString *)extraDataAsJSON;
2224

2325
@optional
2426
- (void)updateJSExceptionWithMessage:(nullable NSString *)message

React/CoreModules/RCTExceptionsManager.mm

+21-9
Original file line numberDiff line numberDiff line change
@@ -35,27 +35,35 @@ - (instancetype)initWithDelegate:(id<RCTExceptionsManagerDelegate>)delegate
3535
return self;
3636
}
3737

38-
- (void)reportSoft:(NSString *)message stack:(NSArray<NSDictionary *> *)stack exceptionId:(double)exceptionId
38+
- (void)reportSoft:(NSString *)message
39+
stack:(NSArray<NSDictionary *> *)stack
40+
exceptionId:(double)exceptionId
41+
extraDataAsJSON:(nullable NSString *)extraDataAsJSON
3942
{
4043
RCTRedBox *redbox = [_moduleRegistry moduleForName:"RedBox"];
4144
[redbox showErrorMessage:message withStack:stack errorCookie:(int)exceptionId];
4245

4346
if (_delegate) {
4447
[_delegate handleSoftJSExceptionWithMessage:message
4548
stack:stack
46-
exceptionId:[NSNumber numberWithDouble:exceptionId]];
49+
exceptionId:[NSNumber numberWithDouble:exceptionId]
50+
extraDataAsJSON:extraDataAsJSON];
4751
}
4852
}
4953

50-
- (void)reportFatal:(NSString *)message stack:(NSArray<NSDictionary *> *)stack exceptionId:(double)exceptionId
54+
- (void)reportFatal:(NSString *)message
55+
stack:(NSArray<NSDictionary *> *)stack
56+
exceptionId:(double)exceptionId
57+
extraDataAsJSON:(nullable NSString *)extraDataAsJSON
5158
{
5259
RCTRedBox *redbox = [_moduleRegistry moduleForName:"RedBox"];
5360
[redbox showErrorMessage:message withStack:stack errorCookie:(int)exceptionId];
5461

5562
if (_delegate) {
5663
[_delegate handleFatalJSExceptionWithMessage:message
5764
stack:stack
58-
exceptionId:[NSNumber numberWithDouble:exceptionId]];
65+
exceptionId:[NSNumber numberWithDouble:exceptionId]
66+
extraDataAsJSON:extraDataAsJSON];
5967
}
6068

6169
static NSUInteger reloadRetries = 0;
@@ -64,7 +72,8 @@ - (void)reportFatal:(NSString *)message stack:(NSArray<NSDictionary *> *)stack e
6472
RCTTriggerReloadCommandListeners(@"JS Crash Reload");
6573
} else if (!RCT_DEV) {
6674
NSString *description = [@"Unhandled JS Exception: " stringByAppendingString:message];
67-
NSDictionary *errorInfo = @{NSLocalizedDescriptionKey : description, RCTJSStackTraceKey : stack};
75+
NSDictionary *errorInfo =
76+
@{NSLocalizedDescriptionKey : description, RCTJSStackTraceKey : stack, RCTJSExtraDataKey : extraDataAsJSON};
6877
RCTFatal([NSError errorWithDomain:RCTErrorDomain code:0 userInfo:errorInfo]);
6978
}
7079
}
@@ -74,15 +83,15 @@ - (void)reportFatal:(NSString *)message stack:(NSArray<NSDictionary *> *)stack e
7483
: (NSArray<NSDictionary *> *)stack exceptionId
7584
: (double)exceptionId)
7685
{
77-
[self reportSoft:message stack:stack exceptionId:exceptionId];
86+
[self reportSoft:message stack:stack exceptionId:exceptionId extraDataAsJSON:nil];
7887
}
7988

8089
RCT_EXPORT_METHOD(reportFatalException
8190
: (NSString *)message stack
8291
: (NSArray<NSDictionary *> *)stack exceptionId
8392
: (double)exceptionId)
8493
{
85-
[self reportFatal:message stack:stack exceptionId:exceptionId];
94+
[self reportFatal:message stack:stack exceptionId:exceptionId extraDataAsJSON:nil];
8695
}
8796

8897
RCT_EXPORT_METHOD(updateExceptionMessage
@@ -131,10 +140,13 @@ - (void)reportFatal:(NSString *)message stack:(NSArray<NSDictionary *> *)stack e
131140
[stackArray addObject:frameDict];
132141
}
133142

143+
NSDictionary *extraData = (NSDictionary *)data.extraData();
144+
NSString *extraDataAsJSON = RCTJSONStringify(extraData, NULL);
145+
134146
if (data.isFatal()) {
135-
[self reportFatal:message stack:stackArray exceptionId:exceptionId];
147+
[self reportFatal:message stack:stackArray exceptionId:exceptionId extraDataAsJSON:extraDataAsJSON];
136148
} else {
137-
[self reportSoft:message stack:stackArray exceptionId:exceptionId];
149+
[self reportSoft:message stack:stackArray exceptionId:exceptionId extraDataAsJSON:extraDataAsJSON];
138150
}
139151
}
140152

0 commit comments

Comments
 (0)