E0092

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.