3

I want a function which, for any given Error, will give me some description of it

protocol CustomError { }

func customDescription(_ error: Error) -> String {
    switch error {
    case let customError as CustomError:
        return "custom error"
    case ???:
        return "not subclass of NSError"
    case let nsError as NSError:
        return "subclass of NSError"
    }
}

Above is not the real code, and I don't want a String description, but a Dictionary, but this is not important in context of the question.

The problem is I don't know how to distinguish Errors which is subclass of NSError and which is not because any swift error could be bridged to NSError. Is it possible in swift?

Maxim Kosov
  • 1,930
  • 10
  • 19
  • 1
    Something like `type(of: error) is NSError.Type` might work. – Martin R Jun 22 '17 at 09:18
  • It is a similar problem as in [Check if `Any` value is object](https://stackoverflow.com/questions/39184911/check-if-any-value-is-object). – Martin R Jun 22 '17 at 09:22
  • I'm not sure I see why you need to separate the `NSError` case from the `Error` case (they're specifically designed to be interoperable) – what is this `Dictionary` you're trying to get? (it does sound important to the context of the question). There's probably a better solution than trying to separate these two cases with casts. – Hamish Jun 22 '17 at 09:26

2 Answers2

10

As you already noticed, any type conforming to Error can be bridged to NSError, therefore error is NSError is always true, and a cast error as NSError does always succeed.

What you can do is to check the dynamic type of the value with type(of:):

type(of: error) is NSError.Type

evaluates to true if error is an instance of NSError or a subclass.

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
2
private protocol _NSError: Error { // private, so _NSError is equal to NSError
}

extension NSError: _NSError {

}

public func customDescription(_ error: Error) -> String {
    switch error {
    case let nsError as _NSError:
        print(nsError as! NSError)
        return "NSError"
    default:
        return "others"
    }
}
linqingmo
  • 41
  • 2