43

Error protocol has only one property localizedDescription. I tried to create custom object inherited from NSObject and Error but I can not override localizedDescription. How can I do that?

This code does not allow me to get custom description:

class MyError: NSObject, Error {
    var desc = ""
    init(str: String) {
        desc = str
    }
    override var description: String {
        get {
            return "MyError: \(desc)"
        }
    }
   var localizedDescription: String {
        get {
            return self.description
        }
    }
}

func test_my_code() {
    let error = MyError(str: "my test string")
    let x = error as Error
    print(x.localizedDescription)
}

Calling function "test_my_code" get unexpected result: "The operation couldn’t be completed...".

What should I do to get result "MyError: my test string" ?

5
  • Won't you need override? Commented Dec 26, 2016 at 4:26
  • can't you extend Error with a new property and then read that instead? Commented Dec 26, 2016 at 4:29
  • 1
    @SunilChauhan no. Anything from protocol should not be overridden. Adding override will break compilation. Commented Dec 26, 2016 at 5:39
  • @Honey I do not want to extend protocol. I just want to make my custom class which conforms Error protocol. Commented Dec 26, 2016 at 5:41
  • @Speakus oops, missed that.! Commented Dec 26, 2016 at 12:01

2 Answers 2

82

The documentation about new Error bridging feature is not clear enough still now, so this answer may need some updates in the near future, but according to SE-0112 and the latest Swift source code, you may need to use LocalizedError rather than Error and implement errorDescription.

class MyError: NSObject, LocalizedError {
    var desc = ""
    init(str: String) {
        desc = str
    }
    override var description: String {
        get {
            return "MyError: \(desc)"
        }
    }
    //You need to implement `errorDescription`, not `localizedDescription`.
    var errorDescription: String? {
        get {
            return self.description
        }
    }
}

func test_my_code() {
    let error = MyError(str: "my test string")
    let x = error as Error
    print(x.localizedDescription)
}
test_my_code() //->MyError: my test string

Other than using LocalizedError, this default implementation works:

(NSError.swift, the link shown above)

public extension Error {
    /// Retrieve the localized description for this error.
    var localizedDescription: String {
        return NSError(domain: _domain, code: _code, userInfo: nil).localizedDescription
    }
}

It is a little complicated how Swift defines _domain or _code from arbitrary types just conforming to Error, but it seems that NSError generates "The operation couldn’t be completed..." for unknown combinations of domain and code.

Sign up to request clarification or add additional context in comments.

1 Comment

Perfect! I was struggling with this and made ugly switch/cases. Works like a charm!
19

If custom type conforms to protocol CustomStringConvertible and provides localized description, then the following extension of LocalizedError might be useful:

extension LocalizedError where Self: CustomStringConvertible {

   var errorDescription: String? {
      return description
   }
}

Example code:

class MyError: LocalizedError, CustomStringConvertible {

   let desc: String

   init(str: String) {
      desc = str
   }

   var description: String {
      let format = NSLocalizedString("Operation error: %@", comment: "Error description")
      return String.localizedStringWithFormat(format, desc)
   }
}


let error = MyError(str: "my test string")
let x = error as Error
print(x.localizedDescription) // Prints "Operation error: my test string"
print(String(describing: x))  // Prints "Operation error: my test string"

1 Comment

This is the best answer here. Seriously, conform to CustomStringConvertible and provide the var description: String.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.