Error
Error prototype extensions
Import
_ <- fat.type.Error
Aliases
- AssignError: assigning a new value to an immutable entry
- AsyncError: asynchronous operation failure
- CallError: a call is made with insufficient arguments
- FileError: file operation failure
- IndexError: index is out of list/text bounds
- KeyError: the key (name) is not found in scope
- SyntaxError: syntax or code structure error
- TypeError: type mismatch on method call, return, or assign
- ValueError: type may be okay, but content is not accepted
Constructor
| Name | Signature | Brief |
|---|---|---|
| Error | (val: Any) | Return val coerced to text wrapped in error |
Prototype members
| Name | Signature | Brief |
|---|---|---|
| isEmpty | <> Boolean | Return true, always |
| nonEmpty | <> Boolean | Return false, always |
| size | <> Number | Return 0, always |
| toText | <> Text | Return error text val |
| freeze | <> Void | Make the value immutable |
| raise | <> Any | Re-throw the stored error |
Example
_ <- fat.type.Error
# Generating an error intentionally
x = Error('ops')
x.toText # yields "Error: ops"
# Inadvertently causing an error
e = undeclared.item # causes a TypeError
e.toText # yields "TypeError: can't resolve scope of 'item'"
Error aliases in practice
# Example of AssignError
x = 10
x = 20 # raises "AssignError: reassignment to immutable > x"
# Example of IndexError
list = [ 1, 2, 3 ]
list[5] # raises "IndexError: out of bounds"
# Example of CallError
add(10) # raises "CallError: nothing to call > add > ..."
Re-raising an error
Since v4.6.0, calling raise on an error value throws it again, preserving the original type and message, so enclosing handlers and fallbacks see the original error.
A handler that returns the bare error already re-raises it automatically (see the failure library), so raise is meant for delayed re-throws: box the error in a Scope to hand it back inert, then raise it where the decision belongs:
failure <- fat.failure
# box the error: returning it bare from the handler would re-raise at once
tryTask = (task: Method): Scope -> {
failure.trapWith(err -> ({ value = null, failed = err }))
{ value = task(), failed = null }
}
outcome = tryTask(-> riskyWork())
outcome.failed != null ? outcome.failed.raise # caller decides: re-throw
outcome.value
A boxed error can be raised more than once. Raising an error that is already the pending failure is a no-op.