Thanks for this feature.
As proposed, the design of DeadlineError makes it difficult to "unwrap" it, in order to throw either the error that caused the operationFailed case, either a reified deadline exceeded error (which does not exist).
Why would one want to perform such unwrapping? Because for good ergonomics, adding withDeadline somewhere in a codebase should not break the existing error handling.
Say some throwing function downloadData performs a network request. I can throw URLError, and some client does perform specific handling of URLError:
// MyModule.swift
/// May throw URLError
public func downloadData() async throws { ... }
// Client.swift
import MyModule
func work() async {
do {
try await downloadData()
} catch is URLError {
// Specific handling of URLError
} catch {
// Handle other errors
}
}
When the author of downloadData adds support for timeout, they do not want to stop throwing URLError in case of network error. It would break the clients. They thus need to unwrap the DeadlineError, rethrow the operation failure, and throw... something else for the deadlineExceeded case. There lies the problem. What can they throw? The error wrapped in the deadlineExceeded is not an error than means "deadline exceeded". There is no such DeadlineExceededError concrete type.
And actually I don't know how to write code that catches the DeadlineError which is generic:
public func downloadData() async throws {
+ do {
+ try await withDeadline(...) {
// Previous code
+ }
+ catch let deadlineError as DeadlineError { // How to write this, actually?
+ switch deadlineError.cause { ... }
+ }
}
To sum up :
-
The current design does not help API authors add a new type of error while preserving the existing errors thrown from their APIs. Consequence: this new type will be recreated many times, by many teams and libraries. The proposal should address this.
-
It is not clear how one is supposed to catch
DeadlineError<OperationError,Clock>and distinguish both causes, when one does not know the actual types used forOperationErrorandClock. -
The two above points look like a poor interaction of the proposed
withDeadlinewith untyped throws. Please let me remind that the When to use typed throws section of SE-0413 says:[...] even with the addition of typed throws to Swift, untyped throws is better for most scenarios.
This means that many codebases use untyped throws pervasively. Identifying and addressing the needs of those codebases is important.