E0092#
Warning name: fragile_catch_all
A catch-all handler performs cleanup and then re-raises the same error. This pattern is fragile because catch-all handlers will not capture asynchronous cancellation in the future, while cleanup must also run when an operation is cancelled.
Erroneous example#
///|
fn operation_that_may_fail() -> Unit raise {
fail("operation failed")
}
///|
pub fn run() -> Unit raise {
try operation_that_may_fail() catch {
error => {
println("cleanup")
raise error
}
}
}
The handler does not recover from or transform the error; it only performs cleanup before propagating it.
Suggestion#
Replace the catch-all handler with errdefer. The cleanup then runs whenever
the following body exits with an error, and the original error is propagated
automatically.
///|
fn operation_that_may_fail() -> Unit raise {
fail("operation failed")
}
///|
pub fn run() -> Unit raise {
errdefer println("cleanup")
operation_that_may_fail()
}
If the handler must inspect the error, keep that logic in catch, but move
independent cleanup into errdefer.