Swift Error Handling For Methods That Do Not Throw [duplicate] Swift Error Handling For Methods That Do Not Throw [duplicate] swift swift

Swift Error Handling For Methods That Do Not Throw [duplicate]


What you are asking is not possible in Swift, as Swift has no facility to handle runtime errors such as out-of-bounds, access violations or failed forced unwrapping during runtime. Your application will terminate if any of these serious programming errors will occur.

Some pointers:

Long story short: Don't short-cut error handling in Swift. Play it safe, always.

Workaround: If you absolutely must catch runtime-errors, you must use process boundaries to guard. Run another program/process and communicate using pipes, sockets, etc.


Faced with an exception thrown from a method which cannot throw. Found out this exception was thrown from objective-c part of API. So you should catch it in old style way using objective-c.

Firstly create objective-c class which takes several blocks in init method - for try, catch and finally.

#import <Foundation/Foundation.h>/** Simple class for catching Objective-c-style exceptions */@interface ObjcTry : NSObject/** *  Initializeer * *  @param tryBlock *  @param catchBlock *  @param finallyBlock * *  @return object */- (_Nonnull id)initWithTry:(nonnull void(^)(void))tryBlock catch:(nonnull void(^)( NSException * _Nonnull exception))catchBlock finally:(nullable void(^)(void))finallyBlock;@end

In .m file:

#import "ObjcTry.h"@implementation ObjcTry- (_Nonnull id)initWithTry:(nonnull void(^)(void))tryBlock catch:(nonnull void(^)( NSException * _Nonnull exception))catchBlock finally:(nullable void(^)(void))finallyBlock{    self = [super init];    if (self) {        @try {            tryBlock ? tryBlock() : nil;        }        @catch (NSException *exception) {            catchBlock ? catchBlock(exception) : nil;        }        @finally {            finallyBlock ? finallyBlock() : nil;        }    }    return self;}@end

Second, add its headers to the Bridging Header file.

#import "ObjcTry.h"

And use it in your swift code like that:

var list: [MyModel]!_ = ObjcTry(withTry: {    // this method throws but not marked so, you cannot even catch this kind of exception using swift method.    if let items = NSKeyedUnarchiver.unarchiveObject(with: data) as? [MyModel] {         list = items    }}, catch: { (exception: NSException) in    print("Could not deserialize models.")}, finally: nil)


I suspect that you'd like to catch errors which is not explicitly marked with "throws".

enter image description here

This makes no sense.You cannot catch other than errors which is explicitly marked with "throws".So, this warning is valid.

For this example, if executed, fatal error: Index out of range will occur.This is runtime error, and you cannot catch it.

For this example, you should check elements size like this, instead of doing try-catch error handling:

enter image description here