Search code examples
swiftcocoa-touchexceptionfoundationnsexception

Catching NSException in Swift


The following code in Swift raises NSInvalidArgumentException exception:

task = NSTask()
task.launchPath = "/SomeWrongPath"
task.launch()

How can I catch the exception? As I understand, try/catch in Swift is for errors thrown within Swift, not for NSExceptions raised from objects like NSTask (which I guess is written in ObjC). I'm new to Swift so may be I'm missing something obvious...

Edit: here's a radar for the bug (specifically for NSTask): openradar.appspot.com/22837476


Solution

  • Here is some code, that converts NSExceptions to Swift 2 errors.

    Now you can use

    do {
        try ObjC.catchException {
    
           /* calls that might throw an NSException */
        }
    }
    catch {
        print("An error ocurred: \(error)")
    }
    

    ObjC.h:

    #import <Foundation/Foundation.h>
    
    @interface ObjC : NSObject
    
    + (BOOL)catchException:(void(^)(void))tryBlock error:(__autoreleasing NSError **)error;
    
    @end
    

    ObjC.m

    #import "ObjC.h"
    
    @implementation ObjC 
    
    + (BOOL)catchException:(void(^)(void))tryBlock error:(__autoreleasing NSError **)error {
        @try {
            tryBlock();
            return YES;
        }
        @catch (NSException *exception) {
            *error = [[NSError alloc] initWithDomain:exception.name code:0 userInfo:exception.userInfo];
            return NO;
        }
    }
    
    @end
    

    Don't forget to add this to your "*-Bridging-Header.h":

    #import "ObjC.h"