NSInvalidArgumentException can't be caught
Originator: | dmaclach | ||
Number: | rdar://8081169 | Date Originated: | 6/10/2010 |
Status: | OPEN | Resolved: | |
Product: | iPhoneSDKq | Product Version: | 3.2 and 4.0 |
Classification: | Serious Bug | Reproducible: | Always |
Summary: You can no longer catch NSInvalidArgumentExceptions that are thrown when you call a method on an object that doesn't have that method. Steps to Reproduce: 1) Build and run attached code Interesting stuff is in ExceptionTestAppDelegate application:didFinishLaunchingWithOptions:. Expected Results: Should see "Caught" logged to console. Actual Results: 2010-06-10 14:28:34.643 ExceptionTest[7524:207] -[ExceptionTestAppDelegate bogusMethod]: unrecognized selector sent to instance 0x5c42430 2010-06-10 14:28:34.646 ExceptionTest[7524:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[ExceptionTestAppDelegate bogusMethod]: unrecognized selector sent to instance 0x5c42430' *** Call stack at first throw: ( 0 CoreFoundation 0x0238b919 __exceptionPreprocess + 185 1 libobjc.A.dylib 0x024d95de objc_exception_throw + 47 2 CoreFoundation 0x0238d42b -[NSObject(NSObject) doesNotRecognizeSelector:] + 187 3 CoreFoundation 0x022fd116 ___forwarding___ + 966 4 CoreFoundation 0x022fccd2 _CF_forwarding_prep_0 + 50 5 ExceptionTest 0x000026c4 -[ExceptionTestAppDelegate application:didFinishLaunchingWithOptions:] + 77 6 UIKit 0x002b0543 -[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 1163 7 UIKit 0x002b29a1 -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 346 8 UIKit 0x002bc452 -[UIApplication handleEvent:withNewEvent:] + 1958 9 UIKit 0x002b5074 -[UIApplication sendEvent:] + 71 10 UIKit 0x002b9ac4 _UIApplicationHandleEvent + 7495 11 GraphicsServices 0x02bf1afa PurpleEventCallback + 1578 12 CoreFoundation 0x0236cdc4 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 52 13 CoreFoundation 0x022cd737 __CFRunLoopDoSource1 + 215 14 CoreFoundation 0x022ca9c3 __CFRunLoopRun + 979 15 CoreFoundation 0x022ca280 CFRunLoopRunSpecific + 208 16 CoreFoundation 0x022ca1a1 CFRunLoopRunInMode + 97 17 UIKit 0x002b2226 -[UIApplication _run] + 625 18 UIKit 0x002bdb58 UIApplicationMain + 1160 19 ExceptionTest 0x00002654 main + 102 20 ExceptionTest 0x000025e5 start + 53 21 ??? 0x00000001 0x0 + 1 ) terminate called after throwing an instance of 'NSException' Regression: This works on SDKs before 3.2. Also is broken on 4.0 Notes: This breaks tests in Google Toolbox for Mac.
Comments
Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!
iPad simulator as well
Just to pile-on. I cannot seem to catch exceptions in the iPad (3.2) simulator either.
Confirmed on iOS 4.0 simulator only
I'm working on a new mock object library that has the ability to tell a mocked/stubbed method to raise an exception. Naturally, it does this by capturing the invocation and injecting it that way so I've run into this bug too. My acceptance test case (just a SenTest method) passes with the device SDK but fails with the simulator SDK.
I've filed a dupe: http://openradar.appspot.com/radar?id=548401
Affects also 4.0.1 and 4.1 beta
Simulators shipped with iOs SDK 4.0.1 and 4.1 beta still suffer from this bug.
Also applies to methods dispatched through forwarding....
code like
will not catch anything....
I filed a bug report with Apple about this too.
Simulator only
With further testing, this appears to affect the simulator only. Works on the device.
Yes so it seems! Tested and confirmed for iOS 3.1.3 and 4.0.
Can't throw exceptions across NSInvocations
Apparently the problem is even worse where exceptions can't be thrown across [NSInvocation invoke] calls.
I can catch exceptions if I do this:
@try { NSInvocation invocation = [self invocation]; objc_msgSend(self, [invocation selector]); } @catch (NSException e) { NSLog(@"%@", e); } but not this
@try { NSInvocation invocation = [self invocation]; [invocation invokeWithTarget:self]; } @catch (NSException e) { NSLog(@"%@", e); }
It doesn't matter what type of exception it is.
Sigh.
Confirmed
I can confirm this for iOS 4.0.