cocoa - Why is raising an NSException not bringing down my application? -


the problem

i'm writing cocoa application , want raise exceptions crash application noisily.

i have following lines in application delegate:

[nsexception raise:nsinternalinconsistencyexception format:@"this should crash application."]; abort(); 

the problem is, don't bring down application - message logged console , app carries on it's merry way.

as understand it, whole point of exceptions they're fired under exceptional circumstances. in these circumstances, want application quit in obvious way. , doesn't happen.

what i've tried

i've tried:

-(void)applicationdidfinishlaunching:(nsnotification *)note     // ...     [self performselectoronmainthread:@selector(crash) withobject:nil waituntildone:yes]; }  -(void)crash {     [nsexception raise:nsinternalinconsistencyexception format:@"this should crash application."];     abort(); } 

which doesn't work ,

-(void)applicationdidfinishlaunching:(nsnotification *)note     // ...     [self performselectorinbackground:@selector(crash) withobject:nil]; }  -(void)crash {     [nsexception raise:nsinternalinconsistencyexception format:@"this should crash application."];     abort(); } 

which, rather confusingly, works expected.

what's going on? doing wrong?

update - nov 16, 2010: there issues answer when exceptions thrown inside ibaction methods. see answer instead:

how can stop hitoolbox catching exceptions?


this expands on david gelhar's answer, , link provided. below how did overriding nsapplication's -reportexception: method. first, create exceptionhandling category nsapplication (fyi, should add 2-3 letter acronym before "exceptionhandling" reduce risk of name clashing):

nsapplication+exceptionhandling.h

#import <cocoa/cocoa.h>  @interface nsapplication (exceptionhandling)  - (void)reportexception:(nsexception *)anexception;  @end 

nsapplication+exceptionhandling.m

#import "nsapplication+exceptionhandling.h"  @implementation nsapplication (exceptionhandling)  - (void)reportexception:(nsexception *)anexception {     (*nsgetuncaughtexceptionhandler())(anexception); }  @end 

second, inside nsapplication's delegate, did following:

appdelegate.m

void exceptionhandler(nsexception *anexception) {     nslog(@"%@", [anexception reason]);     nslog(@"%@", [anexception userinfo]);      [nsapp terminate:nil];  // can call exit() instead if desired }  - (void)applicationwillfinishlaunching:(nsnotification *)anotification {     nssetuncaughtexceptionhandler(&exceptionhandler);      // additional code...      // note: see "update" @ end of post regarding possible glitch here... } 

rather use nsapp's terminate:, can call exit() instead. terminate: more cocoa-kosher, though may want skip applicationshouldterminate: code in event exception thrown , hard-crash exit():

#import "sysexits.h"  // ...  exit(ex_software); 

whenever exception thrown, on main thread, , it's not caught , destroyed, custom uncaught exception handler called instead of nsapplication's. allows crash application, among other things.


update:

there appears small glitch in above code. custom exception handler won't "kick in" , work until after nsapplication has finished calling of delegate methods. means if setup-code inside applicationwillfinishlaunching: or applicationdidfinishlaunching: or awakefromnib:, default nsapplication exception handler appears in-play until after it's initialized.

what means if this:

- (void)applicationwillfinishlaunching:(nsnotification *)anotification {         nssetuncaughtexceptionhandler(&exceptionhandler);          myclass *myclass = [[myclass alloc] init];   // throws exception during init... } 

your exceptionhandler won't exception. nsapplication will, , it'll log it.

to fix this, put initialization code inside @try/@catch/@finally block , can call custom exceptionhandler:

- (void)applicationwillfinishlaunching:(nsnotification *)anotification {     nssetuncaughtexceptionhandler(&exceptionhandler);      @try     {         myclass *myclass = [[myclass alloc] init];   // throws exception during init...     }     @catch (nsexception * e)     {         exceptionhandler(e);     }     @finally     {         // cleanup code...     } } 

now exceptionhandler() gets exception , can handle accordingly. after nsapplication has finished calling delegate methods, nsapplication+exceptionhandling.h category kicks in, calling exceptionhandler() through custom -reportexception: method. @ point don't have worry @try/@catch/@finally when want exceptions raise uncaught exception handler.

i'm little baffled causing this. behind-the-scenes in api. occurs when subclass nsapplication, rather adding category. there may other caveats attached well.


Comments

Popular posts from this blog

c++ - How do I get a multi line tooltip in MFC -

asp.net - In javascript how to find the height and width -

c# - DataTable to EnumerableRowCollection -