Call `throws -> T` function as `-> Result<T, Error>` in Swift

395 views Asked by At

I have some API logic written as a collection of throwing functions:

func getModel() async throws -> Model

When calling these from tasks in a SwiftUI view, I want to catch the error so I can display an error message if necessary. To do this, I have a Result<Model, Error> state variable:

@State var model: Result<Model, Error>?

To call the API function and get its result as a Result, this is the best code I've been able to write:

do {
    model = .success(try await getModel())
} catch let e {
    model = .failure(e)
}

I can't help feeling there's a better way of doing this which I'm missing - the do/catch usage feels like it should be unnecessary.

Is there some easier way I can call throwing functions and get their successful return or their thrown error as a Result?

1

There are 1 answers

0
Jon Shier On BEST ANSWER

You can pretty easily write your own extension to do this, or just call the equivalent manually:

extension Result {
    init(_ work: () async throws -> Success) async where Failure == Error {
        do {
            let value = try await work()
            self = .success(value)
        } catch {
            self = .failure(error)
        }
    }
}

Then you can create the Result using let result = await Result { try await getModel() }. Or even let result = await Result(getModel).