Skip to content

Commit

Permalink
Extend reason message for RCTFatalException (#22532)
Browse files Browse the repository at this point in the history
Summary:
Fixes #22530

As described in the issue, the previous behavior for the `RCTFatal` macro was to truncate the `reason` on the resulting `NSException` to 75 characters. This would ensure the reason would fit on a single line, but resulted in issues debugging errors that occurred in the wild, as many crash logging tools (like Sentry) discard the `name` value of the exception and use the `reason` as their primary identifier. At 75 characters, useful information like the location of the error would usually be truncated.

- [x] This extends the truncation threshold to 175 characters, which should be short enough to prevent full-screen-takeover length errors, but long enough to provide useful context to the error.
- [x] This adds a `userInfo` value to the resulting `NSException`. It copies over the `userInfo` from the `NSError` passed to the macro, and adds an "untruncated message" value that contains the untruncated version of the `NSException`'s reason.

[iOS] [Changed] - RCTFatalExceptions now include more information in their reason and a userInfo.

<!--

  CATEGORY may be:

  - [General]
  - [iOS]
  - [Android]

  TYPE may be:

  - [Added] for new features.
  - [Changed] for changes in existing functionality.
  - [Deprecated] for soon-to-be removed features.
  - [Removed] for now removed features.
  - [Fixed] for any bug fixes.
  - [Security] in case of vulnerabilities.

  For more detail, see https://keepachangelog.com/en/1.0.0/#how

  MESSAGE may answer "what and why" on a feature level. Use this to briefly tell React Native users about notable changes.

  EXAMPLES:

  [General] [Added] - Add snapToOffsets prop to ScrollView component
  [General] [Fixed] - Fix various issues in snapToInterval on ScrollView component
  [iOS] [Fixed] - Fix crash in RCTImagePicker

-->
Pull Request resolved: #22532

Differential Revision: D13373469

Pulled By: cpojer

fbshipit-source-id: ac140d14ce76e1664869437c2c178bdd65ab6e0e
  • Loading branch information
Zack Sheppard authored and kelset committed Dec 12, 2018
1 parent 8ba5d4c commit ba50151
Showing 1 changed file with 15 additions and 2 deletions.
17 changes: 15 additions & 2 deletions React/Base/RCTAssert.m
Expand Up @@ -12,6 +12,7 @@
NSString *const RCTJSStackTraceKey = @"RCTJSStackTraceKey";
NSString *const RCTJSRawStackTraceKey = @"RCTJSRawStackTraceKey";
NSString *const RCTFatalExceptionName = @"RCTFatalException";
NSString *const RCTUntruncatedMessageKey = @"RCTUntruncatedMessageKey";

static NSString *const RCTAssertFunctionStack = @"RCTAssertFunctionStack";

Expand Down Expand Up @@ -128,8 +129,20 @@ void RCTFatal(NSError *error)
@try {
#endif
NSString *name = [NSString stringWithFormat:@"%@: %@", RCTFatalExceptionName, error.localizedDescription];
NSString *message = RCTFormatError(error.localizedDescription, error.userInfo[RCTJSStackTraceKey], 75);
@throw [[NSException alloc] initWithName:name reason:message userInfo:nil];

// Truncate the localized description to 175 characters to avoid wild screen overflows
NSString *message = RCTFormatError(error.localizedDescription, error.userInfo[RCTJSStackTraceKey], 175);

// Attach an untruncated copy of the description to the userInfo, in case it is needed
NSMutableDictionary *userInfo = [error.userInfo mutableCopy];
[userInfo setObject:RCTFormatError(error.localizedDescription, error.userInfo[RCTJSStackTraceKey], -1)
forKey:RCTUntruncatedMessageKey];

// Expected resulting exception information:
// name: RCTFatalException: <underlying error description>
// reason: <underlying error description plus JS stack trace, truncated to 175 characters>
// userInfo: <underlying error userinfo, plus untruncated description plus JS stack trace>
@throw [[NSException alloc] initWithName:name reason:message userInfo:userInfo];
#if DEBUG
} @catch (NSException *e) {}
#endif
Expand Down

0 comments on commit ba50151

Please sign in to comment.