iOS - Global exception handler - iphone

Is there anyway to implement a global exception handler for iPhone apps such that exceptions, instead of silently crashing the app, could allow for some sort of message?
I can understand if it's not do-able since the program may be in an inconsistent state, but it'd be nice to at least tell users "Sorry - something went wrong!"
Thanks!

Check this question for the answer. It seems to indicate that you'll be getting junky stack traces, but you definitely can set a global exception handler. Good luck!

Related

BugSense Framework crashes

i used Bugsense framework in iPhone application to get the crashe logs, and it works fine.
but when i get the crash report from iTunes account, the crash report indicate that there is a crash in bugSense framework.
What this is mean? is it indicate that crashes in applications reported by bugSense ? or it is actual crash in the framework itself?
Please Help.
Thx
It could be, that this is a crash in their SDK. Sadly they perform non-async safe functions in their framework once the crash happened. See http://landonf.bikemonkey.org/code/objc/Reliable_Crash_Reporting.20110912.html for more details on what that means (in this case calling Objective-C code once a crash occurred is unsafe). You might want to contact them to make the fix this possible problem.
But the messages lower in the stack trace also indicate, that this is a crash that happened because of an uncaught exception occurred, which would normally cause another Last Exception Backtrace to appear on top of Thread 0. I am not sure if they have that functionality included. If they do, this causes that block only appear in their own crash report but not in the crash reports iOS creates. Then this is nothing to worry about, except that code above being bad as already mentioned.
If you have enabled immediate dispatch in BugSense, this is probably the reason of this crash, as it isn't guaranteed to be safe.
For more info you can check this: https://github.com/bugsense/plcrashreporter-bugsense/wiki/Using-the-BugSense-2.x-iOS-library , section Enabling immediate dispatch
this may happen when there is no internet connection, try enable immediate dispatch in bug sense

App quits and goes back to home screen, can try + catch deal with it?

When an app suddenly quits and returns back to your home screen, can this always be dealt with alternatively with a try, catch block, or are there exceptions (other than memory leaks, too much memory) that can never be tried and catch, and result in the app quitting?
Many errors cannot be caught with try/catch. In most cases, you should not even attempt to. If you're throwing exceptions or causing a SEGV, then that indicates a serious problem that likely cannot be effectively recovered from. The correct behavior in a mobile environment is to terminate the app. Using tools like TestFlight you can try to recover the logs and stack so that you can resolve the bug.
The way to avoid crashing is careful coding and testing. You should not try to avoid it with a try block.
You need to find and resolve the cause of the app crashing, not just mask it with a try-catch around everything. To answer your question, "no".

How to Handle SIGKILL,SIGABRT, Signal-0 exceptions through Exception Handling in iPhone programming

I have to catch the exception when SIGKILL, SIGABRT, Signal-0 exceptions are raised.
Please Suggest how to handle the above Signals through Exception handling.
Can you please suggest me any sample code to do this?
Thanks in advance.
You can catch most of the unhandled exceptions by registering an NSUncaughtExceptionHandler in your app delegate.
Similarly you can trap most of the signals using sigaction or signal
As you can see in both above links, you can not catch signals of type SIGKILL and SIGSTOP.
try analyzing your code for any possible reasons that cause these signals.
developers with java and C# background are bound to go for exception handling in iOS. Apple has some really good API's to solve the known errors but the program should be made exception free(which i know is difficult). Sigabrt usually occurs when u over release a object and SIGKILL usually occurs when the systems kills your app due to lack of memory. So, i suggest you to read the memory management guide by apple . Also, you can go through this link and this. . Apple has a class defined for exception handling - NSException.
also TRY TO IMPROVE YOUR ACCEPTANCE RATE.
Good luck.

iPhone Production/Release Exception Handling

In advance, please excuse my lack of understanding for iPhone/Objective-C Best Practices; I come from a .NET/C# background.
Although, I've read many posts regarding exception handling for the iPhone, I'm still not exactly clear on what most people do for production code. Also, I haven't been able to find any open source apps with error handling that I would normally expect. Here are my questions:
1) If an unexpected result occurs that would cause the application to eventually fail, would you throw an exception or just wait for it to fail later? For example,
if (![fileManager createDirectoryAtPath: myNewDir
withIntermediateDirectories: YES
attributes: nil
error: &myError]) {
// My app shouldn't continue. Should I raise an exception?
// Or should I just log it and then wait for it to crash later?
}
2) Do you validate parameters? For example, in C# I would usually check for null, and if needed throw an ArgumentNullException.
3) When an app crashes, does the crash info get logged automatically or do I need to set the unhandled exception handler? Can I show a UIAlertView within this method to inform the user something bad happened, instead of having the app just disappear? (If so, I couldn't get it to work.)
4) And finally, why don't I see anyone actually using #try/#catch/#finally? It's used extensively in C#, but I haven't found open source apps using it. (Maybe I'm just looking at the wrong apps.)
Ad 1. The example you give is a somewhat classical example of when one should use a "checked exception" in Java. The caller of the method has to be prepared, that the call can fail for reasons which are outside of what it can control. In particular, in the example given, I would allow the error descriptor object allow to propagate back to the caller:
- (BOOL) prepareDirectories: (NSString*) path error: (NSError**) location {
if( ![fileManager createDirectoryAtPath: path
withIntermediateDirectories: YES
attributes: nil
error: location] ) {
return NO;
}
// ... additional set-up here
return YES;
}
If the error is really not recoverable, you may actually raise an exception, but that will also forfeit any chance to show a proper error message to the user of your application.
Ad 2. Yes, parameter validation is definitely something you should do. And raising an exception for unexpected nils is entirely appropriate. A bad parameter is a "programmer's error" and you cannot guarantee, that the program is still in a consistent state. For example, NSArray raises an exception, if you try to get an element using an non-existent index.
Ad 3. When the app crashes due to an uncaught exception, the fact is logged automatically. You can catch the exception if you really want to display an error message. However, the app is likely to be in an inconsistent state, and should not be allowed to continue, so simply allowing it to go down seems the best solution here.
Ad 4. I don't know.
In the specific case you mention, you should present a notification to the user about what just happened with instructions on how to fix the situation. Except in extreme circumstances your app should not quit. You should let the user fix whatever is wrong, then try again.
Parameter validation depends on a lot of factors. One thing to keep in mind is that in Obj-C it's perfectly valid to send messages to nil (nothing happens if you do) so in a lot of situations you don't need to check for nil. If I'm in a model class I always validate parameters in methods. If I'm not I almost never validate anything, type checking is good enough.
Some information should be logged but it's always helpful to log more specific information to your situation. Ideally you shouldn't ever reach the unhandled exception state.
Cocoa classes will rarely throw exceptions for environmental reasons, they are almost always because you did something wrong. For example, you wouldn't usually put a #try/#catch block around [NSString stringWithString:] because the only way it'll throw an exception is if you try and pass nil. Make sure you aren't passing nil and you won't have to worry about catching exceptions. When a method might fail because of something outside of your control, they usually communicate via an NSError. See the - (BOOL)save:(NSError **)error method of NSManagedObjectContext for example.

Alternative to NSSetUncaughtExceptionHandler on iPhone

I'm trying to make a general error handler for an iPhone app that brings the user to a recovery screen whenever any general error is thrown in the application without putting a try/catch block around every single method in the application.
Using NSSetUncaughtExceptionHandler doesn't work because the application terminates after the handler is run.
Is there any way to change this behavior, or use any other handler that will catch exceptions in general and not cause the application to exit afterward?
And please, no non-answers about whether it's a good or bad idea.
The original poster has probably solved his problem by now. However, for anyone who comes across this in the future...
Matt Gallagher wrote an excellent post on catching unhandled exceptions and signals a few months after this question was posted. I find it to be much more informative than the answer referenced above by Scott.
In particular, Matt's post describes how to attempt a recovery (if appropriate) that allows your app to keep running, and even displays a UIAlertView with error information if you want (hint: it involves creating a new run loop).
This was answered here. You can read more about the responder chain and catching the exceptions here. The write up from 1 is really good and explains how to deal with what you are doing.