I'm trying to use the new typed throws feature in Swift to specify the errors that a function can throw. However, I'm encountering an issue when attempting to catch an error from one function and rethrow a different error type in another function. Here’s my code:
import Foundation
enum A: Error {
case unknown
}
enum B: Error {
case other
}
func foo() throws(A) {
throw .unknown
}
func bar() throws(B) {
do {
try foo()
} catch A.unknown {
throw B.other
} // Thrown expression type 'A' cannot be converted to error type 'B'
}
However, I get the following compilation error:
Thrown expression type 'A' cannot be converted to error type 'B'
I expected that explicitly catching A.unknown and throwing B.other would allow this to work, but it seems the compiler does not allow converting between error types in this manner. Is this a current limitation of typed throws, or am I missing something?
What would be the correct way to rethrow an error of a different type while using typed throws?
Swift version:
swift-driver version: 1.115.1 Apple Swift version 6.0.3 (swiftlang-6.0.3.1.10 clang-1600.0.30.1)
Target: arm64-apple-macosx15.0
Yes, it's a limitation. SE-0413: Typed throws notes that catch clauses will not do exhaustiveness checking in combination with pattern matching:
Note that the only way to write an exhaustive do...catch statement is to have an unconditional catch block. The dynamic checking provided by is or as patterns in the catch block cannot be used to make a catch exhaustive, even if the type specified is the same as the type thrown from the body of the do:
func f() {
do /*infers throws(CatError)*/ {
try callCat()
} catch let ce as CatError {
} // error: do...catch is not exhaustive, so this code rethrows CatError and is ill-formed
}
Note: Exhaustiveness checking in the general is expensive at compile time, and the existing language uses the presence of an unconditional catch block as the indicator for an exhaustive do...catch. See the section on closure thrown type inference for more details about inferring throwing closures.