failure
Error handling and exception management
Import
_ <- fat.failure
Methods
| Name | Signature | Brief |
|---|---|---|
| trap | <> Void | Apply generic error handler |
| trapWith | (handler: Method): Void | Set a handler for errors in context |
| untrap | <> Void | Unset error handler in context |
| noCrash | (unsafe: Method): Any | Continue on error within unsafe method |
Usage notes
When an error is raised if an error handler is found, seeking from the inner execution context to the outer, the handler wrapping the failure is automatically invoked with that error as argument, and the calling context is exited with return value of the error handler.
trapWith
This method binds an error handler to the context of the calling site, e.g. when used inside a method it will protect the logic executed inside the body of that method, and if an error occurs, the method will exit returning whatever is returned by the error handler itself.
you may need to ensure that your error handler will also return a valid type for that context
A handler that returns an Error value re-raises it, so it lands on the next enclosing handler (see the pass-through example below), while returning any other value resolves the failure.
Raising inside a handler
Since v4.6.0, an error raised while a handler (or a ?? fallback) is running propagates as an ordinary raise: the fired handler was already consumed, so the new error lands on the next enclosing handler - or crashes the program if there is none. This means recovery logic that may itself fail, like a reconnect or rollback, can live directly inside the handler. In older versions this was a fatal condition.
A boxed error can later be re-thrown from ordinary control flow by calling err.raise, which propagates the original error with its type and message preserved.
you will have to box the error itself in a
Scopecontainer to return it without re-raising from the handler.
Example
Define an error handler that prints the error and exits:
console <- fat.console
system <- fat.system
sdk <- fat.sdk
simpleErrorHandler = (error) -> {
console.log(error)
sdk.printStack(10)
system.exit(system.failureCode)
}
Finally, use trapWith method to assign the error handler:
failure <- fat.failure
failure.trapWith(simpleErrorHandler)
Trap it!
You can handle expected errors or pass through the unexpected:
failure <- fat.failure
_ <- fat.type.Error
MyError = Error
errorHandler = (e): Number -> e >> {
MyError => 0 # resolve (expected)
_ => e # pass through (unexpected)
}
unsafeMethod = (n) -> {
failure.trapWith(errorHandler)
n < 10 ? MyError('arg is less than ten')
n - 10
}
In this case the program will not crash if you call unsafeMethod(5), but if you comment out the trapWith line, you will see it crashing with MyError.