I have a class I want to redirect user to Error page if theres been an: uncaught exception , a caught exception or a custom exception. I also want to flick off an error email. (so that I'm notified).
I can't access the current View Controller within this class (in the case of an uncaught exception). Because its triggered with the delegate listener onUncaughtException(NSException* exception)
.
How can I access the current view controller, or failing that, modally redirect user to an Error view controller?
#import "ErrorHelper.h"
#import "ErrorViewController.h"
#import "Global.h"
#import "AppDelegate.h"
@implementation ErrorHelper
+(void) handleUncaughtError:(NSException*) exception
{
NSLog(@"Uncaught exception occurred!");
[self sendErrorEmailIfAppropriate:exception :nil];
[self redirectToErrorPage];
}
+(void) handleCaughtError:(NSException*) exception
{
NSLog(@"Error caught!!");
[self sendErrorEmailIfAppropriate:exception :nil];
[self redirectToErrorPage];
}
+(void) handleCaughtCustomError:(NSString*) ref :(NSString*) details
{
NSLog(@"Custom error caught!!");
//can do conditional branching on @ref, to do appropriate action.
[self sendErrorEmailIfAppropriate:nil :details];
[self redirectToErrorPage];
}
+(void) sendErrorEmailIfAppropriate:(NSException*) exception :(NSString*)details
{
if([[Global get] isInTestMode] || [[Global get] isInLiveMode]) {
bool isCustomException = details != nil;
}
}
+(void) redirectToErrorPage
{
/*Try redirect user to error page
E.G:
-There's been an error, our App Dev team will try and resolve the issue for you
-Regards -Dev team
*/
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
}
@end
You should be under the assumption that Cocoa exceptions are non-recoverable. Don't throw them, don't add them to your program. (Using exceptions in C++ is fine, although mixing C++ and ObjC can be unsafe in this regard because ObjC is just not designed for this control flow or cleanup at unwind).
There are a few oddball ObjC APIs which throw, and you could recover from some of them. If possible, use an alternative which does not throw. If you must try/catch in this scenario, then you should make your handler as local to the callsite as possible. Assume an uncaught ObjC exception or one caught by a high level handler is unrecoverable.
Now, because your caught exception is local to the callsite, you can easily add the logic to propagate the error to a view controller or back into the event loop (e.g. an AlertView). Yes, you will likely have some error out parameters or return values to introduce in this case.
Email is a separate question.
I tried this from: exception_handler Its working! Just write your email sending code instead of the alert view.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[window makeKeyAndVisible];
NSSetUncaughtExceptionHandler(&exceptionHandler);
return YES;
}
BOOL exceptionAlertDismissed = FALSE;
void exceptionHandler(NSException *exception)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"App Committed Suicide"
message:@"Oh dear, that wasn't supposed to happen. You will have to restart the application... sorry!"
delegate:[[UIApplication sharedApplication] delegate] cancelButtonTitle:nil otherButtonTitles:@"That's ok!", @"Erm, bye...", nil];
[alert show];
[alert release];
while (exceptionAlertDismissed == FALSE)
{
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
}
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
exceptionAlertDismissed = TRUE;
}
In interface,
@interface ...appDelegate : NSObject <UIApplicationDelegate, UIAlertViewDelegate>
...
void exceptionHandler(NSException *exception);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With