Objective C - Caught exception causes crash - objective-c

I'm doing some Objective C tests. I'm raising a custom exception with this code:
- (double)foo:(int)x{
if (x == 0){
[NSException raise:#"InvalidX" format:#"X can't be 0"];
}
return 1/x;
}
and catching it with this code:
#try {
double y = [self foo:0];
} #catch (NSException *e) {
return;
}
It works good if i run the application in XCode but it crashes when i run the .app:
Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Application Specific Information:
objc[1769]: garbage collection is OFF
*** Terminating app due to uncaught exception 'InvalidX', reason: 'X can't be 0'
*** First throw call stack:
It doesn't look "uncaught"! I can't explain this

Related

How to catch exceptions within BlockCode (Objective C)

Is there a proper way to catch exceptions within block code?
I got the following code:
void(^callback(int) = ^(int respond){
[self DoSomethingWithRespond:respond]; //this throws an exception
};
-(void)DoSomethingWithRespond:(int)respond{
if(respond == 400){
NSException *exception = [NSException
exceptionWithName:#"Failed"
reason:logMessage
userInfo:nil];
#throw exception
}
}
The callback methods gets called from another thread. If the respond is equal to 400 the DoSomethingWithRespond method will throw an exception.
#try {
<#statements#>
}
#catch (NSException *exception) {
<#handler#>
}
#finally {
<#statements#>
}

NSKeyedUnarchiver unarchiveObjectWithData crashes - No way to catch the exception?

I have the following code:
#try {
NSSet *set = [NSKeyedUnarchiver unarchiveObjectWithData:mData];
}
#catch (NSException *exception) {
// Use default data
}
At some point it seems that I wasn't archiving properly and mData is corrupted.
This gives me the following error:
Terminating app due to uncaught exception 'NSInvalidArgumentException',
reason: '*** -[NSKeyedUnarchiver initForReadingWithData:]:
incomprehensible archive (0x14, 0xffffff9a, 0xffffffd0, 0x1d, 0x9, 0x3d, 0x43, 0x3)'
*** Call stack at first throw:
If a try/catch block does not work, how am I supposed to check for an exception here? Shouldn't it be working?
Thank you.
I don't think the try-catch code wasn't working. The log says "uncaught exception" so this error happens somewhere else in your code.

Try Catch Doesn't Work

I'm getting this stack trace in the output window of XCode 4:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Page bottom]: unrecognized selector sent to instance 0xfbdb1f0'
However, the calling code has a try catch
#try {
[self restoreStateWithControlSurfaces:result];
}
#catch (NSException *exception) {
NSLog(#"Failed at restoreStateWithControlSurfaces %#", exception);
retVal = NO;
}
It might have something to do with NSHangOnOtherExceptionMask but I'm not sure how this fits together. How can I get my catch block to work? This is in the simulator for iPad 4.2.
A bug has been reported that prevents NSInvalidArgumentException from being caught. This bug appears to affect the simulator only.

Fail to catch exception from proxy object under Xcode 3.2.3

I use HessianKit to communicate with server. In the situation of network or server down Hessian will throw exception, so I put every Hessian call in a #try ... #catch block. Everything worked fine until I upgraded Xcode from 3.2.2 to 3.2.3. I wrote the some testing code and found under Xcode 3.2.3, catch exception would be failed if the exception was thrown from a proxy object.
MyProxy.h:
#interface MyProxy : NSProxy {
}
#end
MyProxy.m:
#implementation MyProxy
- (id)init {
return self;
}
- (void)forwardInvocation:(NSInvocation *)invocation {
NSLog(#"Call method %#", NSStringFromSelector([invocation selector]));
[NSException raise:#"MyException" format:#"this is an exception"];
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
.....
}
#end
Code using MyProxy:
#try {
MyProxy *p = [[MyProxy alloc] init];
[p doSomething];
[p release];
}
#catch (NSException * e) {
NSLog(#"%#", e);
}
When these code build under xcode 3.2.2, the exception can be catched correctly. But under xcode 3.2.3, the program terminated after output following on the console:
2010-09-08 21:09:29.877 BriefCase[34651:40b] Call method doSomgthing
2010-09-08 21:09:29.879 BriefCase[34651:40b] *** Terminating app due to uncaught exception 'MyException', reason: 'this is an exception'
2010-09-08 21:09:29.880 BriefCase[34651:40b] Stack: (
45955152,
47113004,
45692683,
45692522,
151932,
45426420,
45423090,
9352,
4417860,
4421967,
4447550,
4429047,
4461016,
53399932,
45234332,
45230248,
4420129,
4453234,
8812,
8666
)
terminate called after throwing an instance of 'NSException'
Program received signal: “SIGABRT”.
What can I do?
I filed a bug with Apple, and the reply is:
It has been determined that this is a known issue, which is currently being investigated by engineering. This issue has been filed in our bug database under the original Bug ID# 7995323.
Maybe your project/target/executable settings have been messed up?
Is the "Enable Objective-C Exceptions" box ticked for your configuration/target/etc?
If it is, maybe you should file a bug with Apple here.

access objective-c exception in finally block

Given the following situation:
#try {
#try {
// raises an exception :)
[receiver raisingFirstException];
} #finally {
// raises another exception :)
[otherReceiver raisingFinalException];
}
} #catch (id e) {
printf("exception: %s\n", [[e stringValue] cString]);
}
Is there any way to either get the first exception within the
#finally block or to get both exceptions within the #catch block?
I have code where the #finally block does some checks which may raise an
exception but I don't want to loose the original exception (the root cause).
If there was no original exception but the checks fail I want the
exception they throw.
The best way to do this is to assign the exception to a variable that is accessible from the rest of your block.
NSException *ex;
#try {
#try {
[someObject methodWhichCouldThrowException];
} #catch (NSException *e) {
ex = e;
} #finally {
[anotherObject methodWhichCouldThrowADifferentException];
}
} #catch (NSException *e) {
// From here you can access both the exception thrown by 'someObject'
// as well as the exception thrown by 'anotherObject'.
}