Brian Mahloch
Brian Mahloch

Reputation: 113

Uncaught NSException displayed in UIAlertView

I've implemented the following exception handler using:

NSSetUncaughtExceptionHandler(&ExceptionHandler)

The handler then makes a call to handleException using the following:

[[AppContext alloc] init] performSelectorOnMainThread:@selector(handleException:) withObject:exception waitUntilDone:YES];

Which has been implemented as such:

NSString *message = [NSString stringWithFormat:MSG_UNHANDLED_EXCEPTION_FORMAT, exception.reason, [exception callStackSymbols]];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:TITLE_UNHANDLED_EXCEPTION message:message delegate:self cancelButtonTitle:nil otherButtonTitles:nil];

[alert show];

CFRunLoopRef runLoop = CFRunLoopGetCurrent();
CFArrayRef allModes = CFRunLoopCopyAllModes(runLoop);

while (!_quit) {
    for (NSString *mode in (__bridge NSArray *)allModes) {
        CFRunLoopRunInMode((__bridge CFStringRef)mode, 0.001, false);
    }
}

CFRelease(allModes);

This works well except for the following scenario. I still get the UIAlertView to show but the user interaction is no longer available (user can't scroll message or tap OK).

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(){

    // do long work on another thread...

    dispatch_async(dispatch_get_main_queue(), ^(){

        // updating the UI so get back on main thread...
        // exception occurs in this block (example)...
        @throw [NSException exceptionWithName:@"DispatchAsyncToMainThreadException" reason:@"Example" userInfo:nil];

    });

Note: I am not actually throwing an exception in my production code. This is purely to show where the unhandled exception is being generated.

What am I missing that should be accounted for when the exception is being raised from within a block that has been dispatched back to the main queue.

Upvotes: 0

Views: 590

Answers (1)

Joe
Joe

Reputation: 57179

The documentation for NSSetUncaughtExceptionHandler states that you should be doing last-minute error logging before the application terminates. You should not expect any UI to work at this point and should only be logging somewhere to the file system the details of the error. When the user opens the application again you can let them know something went wrong and possible offer recovery/reporting options.

Discussion
Sets the top-level error-handling function where you can perform last-minute logging before the program terminates.

Upvotes: 1

Related Questions