I'm trying to unify some common error types in my project and hence thought I'd introduce a NetworkError
in my project. This is quite a large project and is hence modularised. I've introduced the NetworkError
type in of my module (let's call it MyLibrary
).
In MyLibrary
:
public struct NetworkError: Error {
public init() {}
}
I've declared NetworkError
as a struct
to simplify the call-sites so I can simply use is NetworkError
when checking the errors, I don't have to check against an exact enum case. I also find an enum the wrong abstraction here as this error will only ever have a single case. This matches the implementation of CancellationError
in the standard library.
I have a method in my iOS app target (let's call this target MyApp
). I have a method in the app target which can throw a NetworkError
.
In MyApp
:
func throwingMethod() throws -> Bool {
throw NetworkError()
}
I want to test that throwingMethod
actually throws a NetworkError
, so I've declared the following test in MyAppTests
:
func testThrowingMethod() {
do {
_ = try throwingMethod()
XCTFail("Method should've thrown")
} catch is CancellationError {
print("CancellationError")
} catch is NetworkError {
print("Success")
} catch {
XCTFail("Unexpected error \(error) thrown instead of \(NetworkError.self)")
}
}
Unexpectedly, the test fails. If I move the declaration of NetworkError
into the app target, the test passes. If I move throwingMethod
and its test to another library, while keeping NetworkError
in MyLibrary
, the test also passes.
If I change NetworkError
to be an enum
, the test passes.
Here's a minimal reproducible example project:
My real project has MyLibrary
declared as an Xcode project in the same workspace as MyApp
, so the issue isn't SPM specific, it was just easier to create a Swift package as a reproducible example.
I'm using Xcode 14.3.1 with Swift 5.8.
This seems like a bug in the runtime - does anyone have any ideas for a workaround until it's fixed in the language itself?