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
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#>
}
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.
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.
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.
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'.
}