Uncaught exception in appdelegate swift 3 - ios

How do I handle all unhandled exceptions in application level?
I tried with NSSetUncaughtExceptionHandler and it called only for NSExceptions.
I would like to handle uncaught exceptions in app level and allow users to continue with app without any crashes by navigating to home (some)page.

I recommend you to use try catch block in your code. It will help to prevent the crashes in your application.
do {
try {
// do something here
// if the call fails, the catch block is executed
}
} catch {
//do something when catch block executes.
}

Related

throw Exception('oops!') vs throw 'oops!'

I notices some code that made me think the Exception function call was optional? E.g., do these two lines perform the same function?
throw Exception('oops!');
throw 'oops!'
No.
The former, throw Exception('oops!');, creates a new Exception object using the Exception constructor, then throws that object.
It can be caught by try { ... } on Exception catch (e) { ... }.
The latter, throw 'oops!'; throws the string object.
It can be caught by try { ... } on String catch (e) { ... }.
Generally, you shouldn't be doing either.
If someone made an error, something that would have been nice to catch at compile-time and reject the program, but which happens to not be that easy to detect, throw an Error (preferably some suitable subclass of Error).
Errors are not intended to be caught, but to make the program fail visibly. Some frameworks do catch errors and log them instead. They're typically able to restart the code which failed and carry on, without needing to understand why.
If your code hit some exceptional situation which the caller should be made aware of (and which prevents just continuing), throw a specific subclass of Exception, one which contains the information the caller needs to programmatically handle that situation. Document that the code throws this particular exception. It's really a different kind of return value more than it's an error report. Exceptions are intended to be caught and handled. Not handling an exception is, itself, an error (which is why it's OK for an uncaught exception to also make the program fail visibly).
If you're debugging, by all means throw "WAT!"; all you want. Just remove it before you release the code.

Difference between 'catch(e)' and 'on Exception catch(e)' in dart?

What is the difference between catch(e) and on Exception catch(e) in dart?
AVOID catches without on clauses.
Using catch clauses without on clauses makes your code prone to encountering unexpected errors that won't be thrown (and thus will go unnoticed).
BAD:
try {
somethingRisky()
} catch(e) {
doSomething(e);
}
GOOD:
try {
somethingRisky()
} on Exception catch(e) {
doSomething(e);
}
Link: avoid_catches_without_on_clauses
The } on Exception catch (e) { will catch all thrown objects implementing Exception.
The excludes most errors (which implement Error),
The } catch (e) { will catch all thrown objects, both exceptions and errors - and anything else that might get thrown. Most thrown objects implement either Exception or Error, but that's just a convention. Any non-null object can be thrown.
I'd actually recommend against on Exception as well. Exceptions are not errors, they are intended for functions as an alternative to returning a value, but exceptions are still just as much part of the function API, and you should only be catching the exceptions that you are actually planning to handle. Since Exception itself has no information, you should be catching the subtype that the function is documented as throwing so you can use the available information to handle the exceptional case.
If you are not going to handle it, you might as well treat the exception as an error.
Using only } catch (e) { to catch everything is reasonable in some situations, mainly in framework code which wraps other user code, and needs to make sure a user code error or unhandled exception doesn't take down the entire program.

Guarantee that no error is thrown in Swift 3 do-catch?

If I have an asynchronous function that throws an error, how can I make sure no error is thrown before some more functions are executed?
do {
try foo()
} catch {
print("error: \(error)")
}
// HOW TO KNOW IF THE CALL WAS SUCCESSFUL HERE
I can have a variable that I change if an error is thrown, but it may be changed in some time if the call is asynchronous. I need to find a way to pause until foo() stops executing so I can be sure no error is thrown.

Difference between try catch and NSSetUncaughtExceptionHandler

I have tried two methods for catching the exceptions. First one is with a try catch and the second one is with the following code in Appdelegate.
void onUncaughtException(NSException* exception)
{
//save exception details
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSSetUncaughtExceptionHandler(&onUncaughtException);
}
The advantage of the second method is we don need to implement try catch blocks in each and every method.
The first one catches the exception, prints it but does not crash the application.. But the second one catches the exception and crashes the application. Is there any way to use the second method to catch exceptions without crashing the application.
NSSetUncaughtExceptionHandler Sets the top-level error-handling function where you can perform last-minute logging before the program terminates. in the onUncaughtException you can do something before crash, but app do crash finally.
#try...#catch...#finally.. is to try to catch possible NSException, if catch, run in the #catch block code, no matter if catch, code will run in #finally block code. Using #try...#catch... will not cause crash finally, this may be the main difference.

Is there any method in appDelegate which is called when application crashes?

I need to save some data in my application, when the application terminates and even if it crashes. I know that applicationWillTerminate is called when application terminates but I am not sure which method is called when application crashes.
Can someone help me here?
Well you could add your own exception handler, to catch the error.
First you need to define the exception method:
void uncaughtExceptionHandler(NSException *exception) {
// You code here, you app will already be unload so you can only see what went wrong.
}
Then tell the app to use your exception handler:
- (void)applicationDidFinishLaunching:(UIApplication *)application {
NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);
// The rest if you code ....
}
There is no way to make the app save data on crashing, since saving could be the reason for the crash!
No, you cannot get to know when the application crashes.

Resources