mirror of
https://github.com/status-im/react-native.git
synced 2025-01-10 01:25:39 +00:00
31b5b0ac01
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
93 lines
2.7 KiB
Objective-C
93 lines
2.7 KiB
Objective-C
/**
|
|
* Copyright (c) 2015-present, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*/
|
|
|
|
#import "RCTExceptionsManager.h"
|
|
|
|
#import "RCTConvert.h"
|
|
#import "RCTDefines.h"
|
|
#import "RCTLog.h"
|
|
#import "RCTRedBox.h"
|
|
#import "RCTRootView.h"
|
|
|
|
@implementation RCTExceptionsManager
|
|
{
|
|
__weak id<RCTExceptionsManagerDelegate> _delegate;
|
|
NSUInteger _reloadRetries;
|
|
}
|
|
|
|
@synthesize bridge = _bridge;
|
|
|
|
RCT_EXPORT_MODULE()
|
|
|
|
- (instancetype)initWithDelegate:(id<RCTExceptionsManagerDelegate>)delegate
|
|
{
|
|
if ((self = [super init])) {
|
|
_delegate = delegate;
|
|
_maxReloadAttempts = 0;
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (instancetype)init
|
|
{
|
|
return [self initWithDelegate:nil];
|
|
}
|
|
|
|
RCT_EXPORT_METHOD(reportSoftException:(NSString *)message
|
|
stack:(NSDictionaryArray *)stack
|
|
exceptionId:(nonnull NSNumber *)exceptionId)
|
|
{
|
|
[_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)
|
|
{
|
|
[_bridge.redBox showErrorMessage:message withStack:stack];
|
|
|
|
if (_delegate) {
|
|
[_delegate handleFatalJSExceptionWithMessage:message stack:stack exceptionId:exceptionId];
|
|
}
|
|
|
|
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]);
|
|
}
|
|
}
|
|
|
|
RCT_EXPORT_METHOD(updateExceptionMessage:(NSString *)message
|
|
stack:(NSDictionaryArray *)stack
|
|
exceptionId:(nonnull NSNumber *)exceptionId)
|
|
{
|
|
[_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.
|
|
RCT_EXPORT_METHOD(reportUnhandledException:(NSString *)message
|
|
stack:(NSDictionaryArray *)stack)
|
|
{
|
|
[self reportFatalException:message stack:stack exceptionId:@-1];
|
|
}
|
|
|
|
@end
|