Yes this is the hardest case of all. And I added it yesterday. I'm more and more convinced that we need to take error conversions into account when we write this proposal. We need to think it through before updating
throws
But I disagree that nothing would improved by it comparing to Result
.
See this example:
struct Kids {}
struct Spouse {}
struct Cat {}
struct Family {
let kids: Kids
let spouse: Spouse
let cat: Cat
}
struct KidsError: Error {}
struct SpouseError: Error {}
struct CatError: Error {}
enum FamilyError: Error {
case kidsError(KidsError)
case spouseError(SpouseError)
case catError(CatError)
}
// With `throws`
func callKids() throws /* KidsError */ -> Kids { throw KidsError() }
func callSpouse() throws /* SpouseError */ -> Spouse { throw SpouseError() }
func callCat() throws /* CatError */ -> Cat { throw CatError() }
func callFamily() throws -> Family {
let kids = try callKids()
let spouse = try callSpouse()
let cat = try callCat()
return Family(kids: kids, spouse: spouse, cat: cat)
}
func callFamilySpecificError() throws /* FamilyError */ -> Family {
do {
let kids = try callKids()
let spouse = try callSpouse()
let cat = try callCat()
return Family(kids: kids, spouse: spouse, cat: cat)
} catch let error as KidsError {
throw FamilyError.kidsError(error)
} catch let error as SpouseError {
throw FamilyError.spouseError(error)
} catch let error as CatError {
throw FamilyError.catError(error)
}
}
// With `Result`
func callKidsResult() -> Result<Kids, KidsError> { Result.failure(KidsError()) }
func callSpouseResult() -> Result<Spouse, SpouseError> { Result.failure(SpouseError()) }
func callCatResult() -> Result<Cat, CatError> { Result.failure(CatError()) }
func callFamilyResult() -> Result<Family, FamilyError> {
return callKidsResult()
.mapError { error in FamilyError.kidsError(error) }
.flatMap { kids in
callSpouseResult()
.mapError { error in FamilyError.spouseError(error)
}.flatMap { spouse in
callCatResult()
.mapError { error in FamilyError.catError(error) }
.map { cat in
Family(kids: kids, spouse: spouse, cat: cat)
}
}
}
}