mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-04-26 05:15:49 +08:00
Create RCTFatal for reporting fatal React events
Summary: public Add RCTFatal for reporting fatal runtime conditions. This centralizes failure handling to one function and allows you to customize how they should be handled. RCTFatal will be logged to the console and as a redbox and will also be triggered by fatal exceptions coming from RCTExceptionsManager. Note that there is no RCTLogFatal, since just logging the fatal condition does not allow us to handle it consistently. Reviewed By: nicklockwood Differential Revision: D2615490 fb-gh-sync-id: 7d8e134419e10a8fb549297054ad955db3f6bee0
This commit is contained in:
committed by
facebook-github-bot-5
parent
d8dd330d41
commit
31b5b0ac01
@@ -13,16 +13,11 @@
|
||||
|
||||
@protocol RCTExceptionsManagerDelegate <NSObject>
|
||||
|
||||
// NOTE: Remove these three methods and the @optional directive after updating the codebase to use only the three below
|
||||
- (void)handleSoftJSExceptionWithMessage:(NSString *)message stack:(NSArray *)stack exceptionId:(NSNumber *)exceptionId;
|
||||
- (void)handleFatalJSExceptionWithMessage:(NSString *)message stack:(NSArray *)stack exceptionId:(NSNumber *)exceptionId;
|
||||
|
||||
@optional
|
||||
|
||||
- (void)handleSoftJSExceptionWithMessage:(NSString *)message stack:(NSArray<NSDictionary *> *)stack;
|
||||
- (void)handleFatalJSExceptionWithMessage:(NSString *)message stack:(NSArray<NSDictionary *> *)stack;
|
||||
- (void)updateJSExceptionWithMessage:(NSString *)message stack:(NSArray<NSDictionary *> *)stack;
|
||||
|
||||
- (void)handleSoftJSExceptionWithMessage:(NSString *)message stack:(NSArray<NSDictionary *> *)stack exceptionId:(NSNumber *)exceptionId;
|
||||
- (void)handleFatalJSExceptionWithMessage:(NSString *)message stack:(NSArray<NSDictionary *> *)stack exceptionId:(NSNumber *)exceptionId;
|
||||
- (void)updateJSExceptionWithMessage:(NSString *)message stack:(NSArray<NSDictionary *> *)stack exceptionId:(NSNumber *)exceptionId;
|
||||
- (void)updateJSExceptionWithMessage:(NSString *)message stack:(NSArray *)stack exceptionId:(NSNumber *)exceptionId;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -43,58 +43,31 @@ RCT_EXPORT_METHOD(reportSoftException:(NSString *)message
|
||||
stack:(NSDictionaryArray *)stack
|
||||
exceptionId:(nonnull NSNumber *)exceptionId)
|
||||
{
|
||||
// TODO(#7070533): report a soft error to the server
|
||||
if (_delegate) {
|
||||
if ([_delegate respondsToSelector:@selector(handleSoftJSExceptionWithMessage:stack:exceptionId:)]) {
|
||||
[_delegate handleSoftJSExceptionWithMessage:message stack:stack exceptionId:exceptionId];
|
||||
} else {
|
||||
[_delegate handleSoftJSExceptionWithMessage:message stack:stack];
|
||||
}
|
||||
return;
|
||||
}
|
||||
[_bridge.redBox showErrorMessage:message withStack:stack];
|
||||
|
||||
if (_delegate) {
|
||||
[_delegate handleSoftJSExceptionWithMessage:message stack:stack exceptionId:exceptionId];
|
||||
}
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(reportFatalException:(NSString *)message
|
||||
stack:(NSDictionaryArray *)stack
|
||||
exceptionId:(nonnull NSNumber *)exceptionId)
|
||||
{
|
||||
if (_delegate) {
|
||||
if ([_delegate respondsToSelector:@selector(handleFatalJSExceptionWithMessage:stack:exceptionId:)]) {
|
||||
[_delegate handleFatalJSExceptionWithMessage:message stack:stack exceptionId:exceptionId];
|
||||
} else {
|
||||
[_delegate handleFatalJSExceptionWithMessage:message stack:stack];
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
[_bridge.redBox showErrorMessage:message withStack:stack];
|
||||
|
||||
if (!RCT_DEBUG) {
|
||||
if (_delegate) {
|
||||
[_delegate handleFatalJSExceptionWithMessage:message stack:stack exceptionId:exceptionId];
|
||||
}
|
||||
|
||||
static NSUInteger reloadRetries = 0;
|
||||
const NSUInteger maxMessageLength = 75;
|
||||
|
||||
if (reloadRetries < _maxReloadAttempts) {
|
||||
|
||||
reloadRetries++;
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:RCTReloadNotification
|
||||
object:nil];
|
||||
|
||||
} else {
|
||||
|
||||
if (message.length > maxMessageLength) {
|
||||
message = [[message substringToIndex:maxMessageLength] stringByAppendingString:@"..."];
|
||||
}
|
||||
|
||||
NSMutableString *prettyStack = [NSMutableString stringWithString:@"\n"];
|
||||
for (NSDictionary *frame in stack) {
|
||||
[prettyStack appendFormat:@"%@@%@:%@\n", frame[@"methodName"], frame[@"lineNumber"], frame[@"column"]];
|
||||
}
|
||||
|
||||
NSString *name = [@"Unhandled JS Exception: " stringByAppendingString:message];
|
||||
[NSException raise:name format:@"Message: %@, stack: %@", message, prettyStack];
|
||||
}
|
||||
static NSUInteger reloadRetries = 0;
|
||||
if (!RCT_DEBUG && reloadRetries < _maxReloadAttempts) {
|
||||
reloadRetries++;
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:RCTReloadNotification object:nil];
|
||||
} else {
|
||||
NSString *description = [@"Unhandled JS Exception: " stringByAppendingString:message];
|
||||
NSDictionary *errorInfo = @{ NSLocalizedDescriptionKey: description, RCTJSStackTraceKey: stack };
|
||||
RCTFatal([NSError errorWithDomain:RCTErrorDomain code:0 userInfo:errorInfo]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,16 +75,11 @@ RCT_EXPORT_METHOD(updateExceptionMessage:(NSString *)message
|
||||
stack:(NSDictionaryArray *)stack
|
||||
exceptionId:(nonnull NSNumber *)exceptionId)
|
||||
{
|
||||
if (_delegate) {
|
||||
if ([_delegate respondsToSelector:@selector(updateJSExceptionWithMessage:stack:exceptionId:)]) {
|
||||
[_delegate updateJSExceptionWithMessage:message stack:stack exceptionId:exceptionId];
|
||||
} else {
|
||||
[_delegate updateJSExceptionWithMessage:message stack:stack];
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
[_bridge.redBox updateErrorMessage:message withStack:stack];
|
||||
|
||||
if (_delegate && [_delegate respondsToSelector:@selector(updateJSExceptionWithMessage:stack:exceptionId:)]) {
|
||||
[_delegate updateJSExceptionWithMessage:message stack:stack exceptionId:exceptionId];
|
||||
}
|
||||
}
|
||||
|
||||
// Deprecated. Use reportFatalException directly instead.
|
||||
@@ -120,4 +88,5 @@ RCT_EXPORT_METHOD(reportUnhandledException:(NSString *)message
|
||||
{
|
||||
[self reportFatalException:message stack:stack exceptionId:@-1];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -647,8 +647,9 @@ RCT_EXPORT_METHOD(removeSubviewsFromContainerWithID:(nonnull NSNumber *)containe
|
||||
}
|
||||
}
|
||||
if (removedChildren.count != atIndices.count) {
|
||||
RCTLogMustFix(@"removedChildren count (%tu) was not what we expected (%tu)",
|
||||
removedChildren.count, atIndices.count);
|
||||
NSString *message = [NSString stringWithFormat:@"removedChildren count (%tu) was not what we expected (%tu)",
|
||||
removedChildren.count, atIndices.count];
|
||||
RCTFatal(RCTErrorWithMessage(message));
|
||||
}
|
||||
return removedChildren;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user