Say I have a Result<Data, NetworkError> from a network response. Next I want to turn it into Result<Model, NetworkError>.
Or better yet: Result<Model, ModelRelatedError>
My initial approach was to use map, but that's where I realized I needed a throwing closure. Also, it only handles mapping the success or the failure (mapError, I believe?), but not both.
let networkResult: Result<Data, NetworkData>( ... )
let modelResult = networkResult.map { data in
JSONDecoder(), etc. etc. ...
// now I need to handle do / catch in here...
}
I could write this out the slightly longer way, with a switch statement, do, catch, and so on. Maybe throw it in an extension. I wanted to see if there are some best practices / patterns others use here.
For now you can use flatMap and use an inner Result to capture the transform. But yes, I plan on making a formal pitch to add throwing transforms. In the meantime it’s pretty easy to add yourself.
Is there a way to propagate a new error type? Say, after the model decoding fails, i want to end up with Result<Model, ModelError>. (the underlying networking layer in the example does not know of this decoding error, only network specific errors). So mapping Result<Data, NetworkError> to Result<Model, ModelError> .
You can call mapError to encapsulate the error in your type. Or, in your flatMap manually handle the decode using do / catch and do both in the same step.
You want map/flatMap when the error type stays the same.
If you want to change both at the same time you might prefer using do-catch + .get().
e.g.
let networkResult = ...
do {
let data = try networkResult.get()
let modelResult = ... something with data ...
} catch {
let modelError = ... something with error ...
return .failure(modelError)
}