0

In the code below, I am getting the error :

enum errors: Error {
    case too_short, too_obvs
}

func checkPassword(_ passwordEntered: String) throws -> String {
    if passwordEntered.count < 5 {
        throw errors.too_short
    }
    if passwordEntered == "12345" {
        throw errors.too_obvs
    }
    if passwordEntered.count >= 10 {
        return "Password set."
    }
}

let myPassword = "12345"

do {
    let result = try checkPassword(myPassword)
    print("\(result) is your password rating.")
} catch errors.too_short { // customised catch
    print("Password is too short.")
} catch errors.too_obvs {
    print("A 5 yr old would guess that password!")
} catch { // default catch
    print("Error. Enter a stronger password.")
    print("Error: \(error.localizedDescription)") // -> to use default Swift error explanations
}

Error -

error: value of type 'Error' has no member 'localizedDescription'

print("Error: \(error.localizedDescription)") // -> to use default Swift error explanations

I don't understand why it's pointing out 'Error' when it isn't even used in the print.

I do not understand what I am missing here. Any help will be appreciated. Thank you.

Rob
  • 415,655
  • 72
  • 787
  • 1,044
HarshDarji
  • 156
  • 8
  • Is this in a playground? – matt Oct 20 '22 at 02:51
  • It's possible that you're getting a bogus error because of an error above -- you're missing a return in your `checkPassword` function -- it needs to return from all code paths – jnpdx Oct 20 '22 at 02:52
  • Although I have also seen playgrounds spit out bogus errors for string interpolations. See my https://stackoverflow.com/questions/73763834/playground-string-interpolation The workaround is simple, just assign to a variable first. – matt Oct 20 '22 at 02:55
  • @jnpdx there is a return in the function. The last line of the function. – HarshDarji Oct 20 '22 at 03:25
  • @matt yes this was playground. However, I typed this is replit too. Same error. – HarshDarji Oct 20 '22 at 03:26
  • 2
    @HarshDarji A function must return from *all code paths*. You only return if `passwordEntered.count >= 10`. The compiler is giving you an error there. – jnpdx Oct 20 '22 at 03:26
  • 1
    Did you look at the link? Repl has the same issue. Just do what I said and don't try this string interpolation in a playground. – matt Oct 20 '22 at 03:27

1 Answers1

1

As others have noted, there are idiosyncrasies of Playgrounds. Try the code in an actual app and you will not get that particular error, but rather one pointing out that checkPassword is not returning a value for every path of execution.

But to answer the broader question of how one creates localized descriptions for custom error types, one would add LocalizedError conformance:

enum PasswordError: Error {
    case tooShort
    case tooObvious
}

extension PasswordError: LocalizedError {
    var errorDescription: String? {
        switch self {
        case .tooShort:   return NSLocalizedString("Password is too short", comment: "PasswordError")
        case .tooObvious: return NSLocalizedString("Password is too obvious", comment: "PasswordError")
        }
    }
}

And then you have a routine that returns a string for all paths of execution (but you don’t have to have a separate catch for each error if you don’t want).

func passwordRating(_ passwordEntered: String) throws -> String {
    if passwordEntered.count < 5 { throw PasswordError.tooShort }
    if passwordEntered == "12345" { throw PasswordError.tooObvious }

    if passwordEntered.count >= 10 { return "Excellent" }

    return "Acceptable"
}

func validatePassword() {
    do {
        let rating = try passwordRating(myPassword)
        print("\(rating) is your password rating.")
    } catch {
        print("Error. Enter a stronger password.")
        print("Error: \(error.localizedDescription)")
    }
}
Rob
  • 415,655
  • 72
  • 787
  • 1,044
  • But `localizedDescription` is guaranteed by the Error protocol. The issue is not the wisdom or otherwise, it's the compile error. – matt Oct 20 '22 at 03:23
  • I totally agree but I repeat, that's irrelevant to the question. – matt Oct 20 '22 at 03:26
  • But that's not the cause of this bogus compile error. – matt Oct 20 '22 at 18:22
  • Correct. I was fixing the bug in the code not trying to address the Playgrounds idiosyncrasies. – Rob Oct 20 '22 at 20:28