How to tell apart native Swift Errors from NSError?

I have a mixed ObjC/Swift repo and am trying to improve the error reporting code. Swift Error instances are freely convertible to NSError, but their default localizedDescription isn't very useful. I'd like to write separate code to handle native Swift errors. Is there a recommended way to tell them apart from NSError objects that originated in ObjC code?

I don't have access to a mac to try r/n, but iirc you can avoid the automatic conversion by checking if type(of: errorInstance) is NSError.Type) instead of directly testing the instance.

Please, provide some more details about your task and goals. Do you want to handle these errors in Obj-C context or do they round trip to Obj-C and then finally handled in Swift context? How do you see the final result if everything is done as you want?

According to what is written, I can recommend to read about LocalizedError and CustomNSError protocols. It may also be valuable to conform to CustomStringConvertible and CustomDebugStringConvertible depending in your purposes.
In my current project we have a BaseError protocol with lots of functionality out of the box and CustomNSError default implementation which is currently suitable for all situations.

I'm aware of the protocols, I'm just looking for a short term improvement while we're working on a more comprehensive solution. Ideally one that doesn't require me to change other teams' code.

Thanks, I'll try that.

Note that this won't work with NSError subclasses. This would:

func isNativeError(_ a: Error) -> Bool {
    enum KnownErrorType: Error { case x }
    let a = a as NSError
    let k = KnownErrorType.x as NSError
    return type(of: a) == type(of: k)

No, that’s not right either, there’s no guarantee that all boxed Swift errors share the same type. And MyNSErrorSubclass.self is NSError.Type is true anyway.

Good catch. So the proper check is not:

let error: Error = ...
let isNative = type(of: error) != NSError.self // ❌


let error: Error = ...
let isNative = !(type(of: error) is NSError.Type) // ✅
1 Like

That works, thanks for your help!