inokey
inokey

Reputation: 6170

Returning value for function that throws

I've got a pretty simple question but I could only find a similar answer in C++ thread. Compiler complains on getUserFromServer function stating that it requires return value even though it can catch an exception. It is obvious WHY it asks for return value but I'm not sure how to handle the situation properly.

One way is to create some sort of dummy user and return it but it doesn't sound any good. Another way is by making return type Optional but it's just moving responsibility for nil-checks to another level, which is probably not a good idea. Any help would help.

Here's a setup to simulate behaviour I expect in real code.

enum TestError: Error {
    case JustError
}

class User {}
class ServerClient {
    func getUser(really: Bool) throws -> User {
        var uza: User?
        if really {
            uza = User()
        }
        guard let user = uza else {
            throw TestError.JustError
        }
        return user
    }
}

func getUserFromServer() -> User {

    let client = ServerClient()
    let user: User

    do {
        user = try client.getUser(really: true)
        return user
    } catch TestError.JustError {
        print("just an error occured")
    } catch {
        print("something terrible happened")
    }
} //Error: missing return in a function

Upvotes: 5

Views: 3096

Answers (1)

Rob Napier
Rob Napier

Reputation: 299355

So imagine I'm a the caller, and I write this line of code:

let user = getUserFromServer()
print(user)

It fails somehow. Great. What do you want to happen? What should user be? What should print? (There's no right answer here; the question really is what do you want it to be?)

If you want user to be nil, then getUserFromServer should return User?. If you want user to be some default user, then you'll need a way to create that. If you want the caller to not print at all (and instead handle some error), then getUserFromServer() should throw. If you want it to crash, then you need to add a fatalError inside getUserFromServer. These are all valid, but it has to do something, and what that something is, is up to you.

That said, if the question is just advice about what it should be, looking at this code you should probably default to making it an optional unless you need some other behavior. That would be the "normal" thing here since you already "handled" the error.

Upvotes: 8

Related Questions