Reputation: 10417
I'm running into a situation in iOS (and OS X) where exceptions from NSKeyedUnarchiver cause binary-only third-party frameworks to crash my app (when deployed in the field) when they try to unarchive a corrupt archive, thus forcing users to delete and reinstall the app. This doesn't happen often, but I'd like that number to be zero.
I can't solve the problem by wrapping the NSKeyedUnarchiver calls, both because I don't have the source code and because those calls are not the direct result of anything that my code does; they run on arbitrary background threads at arbitrary times.
I'm currently swizzling the NSKeyedUnarchiver class so that reading a corrupt archive returns nil (as though the file were not there) rather than throwing an exception, but I can't be certain whether any of those third-party frameworks might do things correctly (with an @try/@catch block) and might break in interesting ways if I do so.
It would be helpful if I could somehow examine the Objective-C exception handling tree (or equivalent) to determine whether an exception handler would catch an exception if thrown, and if so, which handler. That way, my patched method could return nil if the exception would make it all the way up to Crashlytics (which would rethrow it, causing a crash), but could rethrow the exception if some other handler would catch it.
Is such a thing possible, and if so, how?
Upvotes: 2
Views: 444
Reputation: 9570
If you're not sure that wrapping third-party library code with @try/@catch
is good enough you can hook NSKeyedUnarchiver
methods to replace them with exact same wrapper thus making sure that exception is never gets thrown outside. Here is pseudo-code:
@try {
//call original NSKeyedUnarchiver implementation
}
@catch {
return nil;
}
Objc runtime has public APIs that can do such a thing
Upvotes: 0
Reputation: 17081
Why not wrap your exception-throwing callsite in a try/catch/finally?
@try {
//call to your third party unarchiver
}
@catch {
//remove your corrupted archive
}
@finally {
//party
}
Rolling your own global exception handler may also be of use here, ala: How do you implement global iPhone Exception Handling?
Upvotes: 1