Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 37 additions & 37 deletions ios/ReactNativeExceptionHandler.m
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@


// CONSTANTS
NSString * const UncaughtExceptionHandlerSignalExceptionName = @"UncaughtExceptionHandlerSignalExceptionName";
NSString * const UncaughtExceptionHandlerSignalKey = @"UncaughtExceptionHandlerSignalKey";
NSString * const UncaughtExceptionHandlerAddressesKey = @"UncaughtExceptionHandlerAddressesKey";
volatile int32_t UncaughtExceptionCount = 0;
const int32_t UncaughtExceptionMaximum = 10;
const NSInteger UncaughtExceptionHandlerSkipAddressCount = 4;
const NSInteger UncaughtExceptionHandlerReportAddressCount = 5;
NSString * const RNUncaughtExceptionHandlerSignalExceptionName = @"RNUncaughtExceptionHandlerSignalExceptionName";
NSString * const RNUncaughtExceptionHandlerSignalKey = @"RNUncaughtExceptionHandlerSignalKey";
NSString * const RNUncaughtExceptionHandlerAddressesKey = @"RNUncaughtExceptionHandlerAddressesKey";
volatile int32_t RNUncaughtExceptionCount = 0;
const int32_t RNUncaughtExceptionMaximum = 10;
const NSInteger RNUncaughtExceptionHandlerSkipAddressCount = 4;
const NSInteger RNUncaughtExceptionHandlerReportAddressCount = 5;


@implementation ReactNativeExceptionHandler
Expand All @@ -34,18 +34,18 @@ - (dispatch_queue_t)methodQueue
//variable that holds the default native error handler
void (^defaultNativeErrorCallbackBlock)(NSException *exception, NSString *readeableException) =
^(NSException *exception, NSString *readeableException){

UIAlertController* alert = [UIAlertController
alertControllerWithTitle:@"Unexpected error occured"
message:[NSString stringWithFormat:@"%@\n%@",
@"Appologies..The app will close now \nPlease restart the app\n",
readeableException]
preferredStyle:UIAlertControllerStyleAlert];

UIApplication* app = [UIApplication sharedApplication];
UIViewController * rootViewController = app.delegate.window.rootViewController;
[rootViewController presentViewController:alert animated:YES completion:nil];

[NSTimer scheduledTimerWithTimeInterval:5.0
target:[ReactNativeExceptionHandler class]
selector:@selector(releaseExceptionHold)
Expand All @@ -66,7 +66,7 @@ - (dispatch_queue_t)methodQueue
jsErrorCallbackBlock = ^(NSException *exception, NSString *readeableException){
callback(@[readeableException]);
};

NSSetUncaughtExceptionHandler(&HandleException);
signal(SIGABRT, SignalHandler);
signal(SIGILL, SignalHandler);
Expand Down Expand Up @@ -102,16 +102,16 @@ - (void)handleException:(NSException *)exception
{
NSString * readeableError = [NSString stringWithFormat:NSLocalizedString(@"%@\n%@", nil),
[exception reason],
[[exception userInfo] objectForKey:UncaughtExceptionHandlerAddressesKey]];
[[exception userInfo] objectForKey:RNUncaughtExceptionHandlerAddressesKey]];
dismissApp = false;

if(nativeErrorCallbackBlock != nil){
nativeErrorCallbackBlock(exception,readeableError);
}else{
defaultNativeErrorCallbackBlock(exception,readeableError);
}
jsErrorCallbackBlock(exception,readeableError);

CFRunLoopRef runLoop = CFRunLoopGetCurrent();
CFArrayRef allModes = CFRunLoopCopyAllModes(runLoop);
while (!dismissApp)
Expand All @@ -126,18 +126,18 @@ - (void)handleException:(NSException *)exception
i++;
}
}

CFRelease(allModes);

NSSetUncaughtExceptionHandler(NULL);
signal(SIGABRT, SIG_DFL);
signal(SIGILL, SIG_DFL);
signal(SIGSEGV, SIG_DFL);
signal(SIGFPE, SIG_DFL);
signal(SIGBUS, SIG_DFL);
signal(SIGPIPE, SIG_DFL);
kill(getpid(), [[[exception userInfo] objectForKey:UncaughtExceptionHandlerSignalKey] intValue]);

kill(getpid(), [[[exception userInfo] objectForKey:RNUncaughtExceptionHandlerSignalKey] intValue]);

}

Expand All @@ -148,19 +148,19 @@ - (void)handleException:(NSException *)exception

void HandleException(NSException *exception)
{
int32_t exceptionCount = OSAtomicIncrement32(&UncaughtExceptionCount);
if (exceptionCount > UncaughtExceptionMaximum)
int32_t exceptionCount = OSAtomicIncrement32(&RNUncaughtExceptionCount);
if (exceptionCount > RNUncaughtExceptionMaximum)
{
return;
}

NSArray *callStack = [ReactNativeExceptionHandler backtrace];
NSMutableDictionary *userInfo =
[NSMutableDictionary dictionaryWithDictionary:[exception userInfo]];
[userInfo
setObject:callStack
forKey:UncaughtExceptionHandlerAddressesKey];
forKey:RNUncaughtExceptionHandlerAddressesKey];

[[[ReactNativeExceptionHandler alloc] init]
performSelectorOnMainThread:@selector(handleException:)
withObject:
Expand All @@ -173,35 +173,35 @@ void HandleException(NSException *exception)

void SignalHandler(int signal)
{
int32_t exceptionCount = OSAtomicIncrement32(&UncaughtExceptionCount);
if (exceptionCount > UncaughtExceptionMaximum)
int32_t exceptionCount = OSAtomicIncrement32(&RNUncaughtExceptionCount);
if (exceptionCount > RNUncaughtExceptionMaximum)
{
return;
}

NSMutableDictionary *userInfo =
[NSMutableDictionary
dictionaryWithObject:[NSNumber numberWithInt:signal]
forKey:UncaughtExceptionHandlerSignalKey];
forKey:RNUncaughtExceptionHandlerSignalKey];

NSArray *callStack = [ReactNativeExceptionHandler backtrace];
[userInfo
setObject:callStack
forKey:UncaughtExceptionHandlerAddressesKey];
forKey:RNUncaughtExceptionHandlerAddressesKey];

[[[ReactNativeExceptionHandler alloc] init]
performSelectorOnMainThread:@selector(handleException:)
withObject:
[NSException
exceptionWithName:UncaughtExceptionHandlerSignalExceptionName
exceptionWithName:RNUncaughtExceptionHandlerSignalExceptionName
reason:
[NSString stringWithFormat:
NSLocalizedString(@"Signal %d was raised.", nil),
signal]
userInfo:
[NSDictionary
dictionaryWithObject:[NSNumber numberWithInt:signal]
forKey:UncaughtExceptionHandlerSignalKey]]
forKey:RNUncaughtExceptionHandlerSignalKey]]
waitUntilDone:YES];
}

Expand All @@ -215,19 +215,19 @@ + (NSArray *)backtrace
void* callstack[128];
int frames = backtrace(callstack, 128);
char **strs = backtrace_symbols(callstack, frames);

int i;
NSMutableArray *backtrace = [NSMutableArray arrayWithCapacity:frames];
for (
i = UncaughtExceptionHandlerSkipAddressCount;
i < UncaughtExceptionHandlerSkipAddressCount +
UncaughtExceptionHandlerReportAddressCount;
i = RNUncaughtExceptionHandlerSkipAddressCount;
i < RNUncaughtExceptionHandlerSkipAddressCount +
RNUncaughtExceptionHandlerReportAddressCount;
i++)
{
[backtrace addObject:[NSString stringWithUTF8String:strs[i]]];
}
free(strs);

return backtrace;
}

Expand Down