Skip to content

Commit b4f1f88

Browse files
committed
Don't overwrite pre-existing native handlers on iOS
1 parent c4785de commit b4f1f88

File tree

1 file changed

+32
-19
lines changed

1 file changed

+32
-19
lines changed

ios/ReactNativeExceptionHandler.m

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -28,45 +28,52 @@ - (dispatch_queue_t)methodQueue
2828
//variable to hold the custom error handler passed while customizing native handler
2929
void (^nativeErrorCallbackBlock)(NSException *exception, NSString *readeableException);
3030

31+
// variable to hold the previously defined error handler
32+
NSUncaughtExceptionHandler* previousNativeErrorCallbackBlock;
33+
34+
BOOL callPreviousNativeErrorCallbackBlock = false;
35+
3136
//variable to hold the js error handler when setting up the error handler in RN.
3237
void (^jsErrorCallbackBlock)(NSException *exception, NSString *readeableException);
3338

3439
//variable that holds the default native error handler
3540
void (^defaultNativeErrorCallbackBlock)(NSException *exception, NSString *readeableException) =
3641
^(NSException *exception, NSString *readeableException){
37-
42+
3843
UIAlertController* alert = [UIAlertController
3944
alertControllerWithTitle:@"Unexpected error occured"
4045
message:[NSString stringWithFormat:@"%@\n%@",
4146
@"Apologies..The app will close now \nPlease restart the app\n",
4247
readeableException]
4348
preferredStyle:UIAlertControllerStyleAlert];
44-
49+
4550
UIApplication* app = [UIApplication sharedApplication];
4651
UIViewController * rootViewController = app.delegate.window.rootViewController;
4752
[rootViewController presentViewController:alert animated:YES completion:nil];
48-
53+
4954
[NSTimer scheduledTimerWithTimeInterval:5.0
5055
target:[ReactNativeExceptionHandler class]
5156
selector:@selector(releaseExceptionHold)
5257
userInfo:nil
5358
repeats:NO];
5459
};
5560

56-
5761
// ====================================
5862
// REACT NATIVE MODULE EXPOSED METHODS
5963
// ====================================
6064

6165
RCT_EXPORT_MODULE();
6266

6367
// METHOD TO INITIALIZE THE EXCEPTION HANDLER AND SET THE JS CALLBACK BLOCK
64-
RCT_EXPORT_METHOD(setHandlerforNativeException:(RCTResponseSenderBlock)callback)
68+
RCT_EXPORT_METHOD(setHandlerforNativeException:(BOOL)callPreviouslyDefinedHandler withCallback: (RCTResponseSenderBlock)callback)
6569
{
6670
jsErrorCallbackBlock = ^(NSException *exception, NSString *readeableException){
6771
callback(@[readeableException]);
6872
};
69-
73+
74+
previousNativeErrorCallbackBlock = NSGetUncaughtExceptionHandler();
75+
callPreviousNativeErrorCallbackBlock = callPreviouslyDefinedHandler;
76+
7077
NSSetUncaughtExceptionHandler(&HandleException);
7178
signal(SIGABRT, SignalHandler);
7279
signal(SIGILL, SignalHandler);
@@ -105,14 +112,19 @@ - (void)handleException:(NSException *)exception
105112
[exception reason],
106113
[[exception userInfo] objectForKey:RNUncaughtExceptionHandlerAddressesKey]];
107114
dismissApp = false;
108-
115+
116+
117+
if (callPreviousNativeErrorCallbackBlock && previousNativeErrorCallbackBlock) {
118+
previousNativeErrorCallbackBlock(exception);
119+
}
120+
109121
if(nativeErrorCallbackBlock != nil){
110122
nativeErrorCallbackBlock(exception,readeableError);
111123
}else{
112124
defaultNativeErrorCallbackBlock(exception,readeableError);
113125
}
114126
jsErrorCallbackBlock(exception,readeableError);
115-
127+
116128
CFRunLoopRef runLoop = CFRunLoopGetCurrent();
117129
CFArrayRef allModes = CFRunLoopCopyAllModes(runLoop);
118130
while (!dismissApp)
@@ -127,19 +139,19 @@ - (void)handleException:(NSException *)exception
127139
i++;
128140
}
129141
}
130-
142+
131143
CFRelease(allModes);
132-
144+
133145
NSSetUncaughtExceptionHandler(NULL);
134146
signal(SIGABRT, SIG_DFL);
135147
signal(SIGILL, SIG_DFL);
136148
signal(SIGSEGV, SIG_DFL);
137149
signal(SIGFPE, SIG_DFL);
138150
signal(SIGBUS, SIG_DFL);
139151
signal(SIGPIPE, SIG_DFL);
140-
152+
141153
kill(getpid(), [[[exception userInfo] objectForKey:RNUncaughtExceptionHandlerSignalKey] intValue]);
142-
154+
143155
}
144156

145157

@@ -154,14 +166,14 @@ void HandleException(NSException *exception)
154166
{
155167
return;
156168
}
157-
169+
158170
NSArray *callStack = [ReactNativeExceptionHandler backtrace];
159171
NSMutableDictionary *userInfo =
160172
[NSMutableDictionary dictionaryWithDictionary:[exception userInfo]];
161173
[userInfo
162174
setObject:callStack
163175
forKey:RNUncaughtExceptionHandlerAddressesKey];
164-
176+
165177
[[[ReactNativeExceptionHandler alloc] init]
166178
performSelectorOnMainThread:@selector(handleException:)
167179
withObject:
@@ -179,17 +191,17 @@ void SignalHandler(int signal)
179191
{
180192
return;
181193
}
182-
194+
183195
NSMutableDictionary *userInfo =
184196
[NSMutableDictionary
185197
dictionaryWithObject:[NSNumber numberWithInt:signal]
186198
forKey:RNUncaughtExceptionHandlerSignalKey];
187-
199+
188200
NSArray *callStack = [ReactNativeExceptionHandler backtrace];
189201
[userInfo
190202
setObject:callStack
191203
forKey:RNUncaughtExceptionHandlerAddressesKey];
192-
204+
193205
[[[ReactNativeExceptionHandler alloc] init]
194206
performSelectorOnMainThread:@selector(handleException:)
195207
withObject:
@@ -216,7 +228,7 @@ + (NSArray *)backtrace
216228
void* callstack[128];
217229
int frames = backtrace(callstack, 128);
218230
char **strs = backtrace_symbols(callstack, frames);
219-
231+
220232
int i;
221233
NSMutableArray *backtrace = [NSMutableArray arrayWithCapacity:frames];
222234
for (
@@ -228,8 +240,9 @@ + (NSArray *)backtrace
228240
[backtrace addObject:[NSString stringWithUTF8String:strs[i]]];
229241
}
230242
free(strs);
231-
243+
232244
return backtrace;
233245
}
234246

235247
@end
248+

0 commit comments

Comments
 (0)