# Error Handling
Errors in Graphix are represented by the `Error<'a>` type. A new instance of
which can be created with the `error` function. e.g.
```graphix
〉error(`Foo)
-: Error<'a: `Foo>
error:"Foo"
```
## Try Catch and ?
While errors are normal values, and can be matched in select, they can also be
thrown and handled like exceptions. The `?` operator throws errors generated by
the expression on it's left to the nearest try catch block in dynamic scope. for
example,
```graphix
〉let a = [1, 2, 3, 4]
〉try a[15]? catch(e) => println(e)
-: i64
error:[["cause", null], ["error", ["ArrayIndexError", "array index out of bounds"]], ["ori", [["parent", null], ["source", "Unspecified"], ["text", "try a[15]? catch(e) => println(e)"]]], ["pos", [["column", i32:5], ["line", i32:1]]]]
```
Catches the array index error and prints it's full context to stdout. Every
error raised with `?` is wrapped in an `ErrChain` struct, the full definition of
which is,
```graphix
type Pos = {
line: i32,
column: i32
};
type Source = [
`File(string),
`Netidx(string),
`Internal(string),
`Unspecified
];
type Ori = {
parent: [Ori, null],
source: Source,
text: string
};
type ErrChain<'a> = {
cause: [ErrChain<'a>, null],
error: 'a,
ori: Ori,
pos: Pos
}
```
This gives the full context of where the error happened, and whether it was
previously caught and reraised, giving the full history back to the first time
it was ever raised.
The scope is dynamic, not lexical, mirroring exception systems that unwind the
stack,
```graphix
-: i64
error:[["cause", null], ["error", ["ArithError", "attempt to divide by zero"]], ["ori", [["parent", null], ["source", "Unspecified"], ["text", "let div0 = try |x| x / 0 catch(e) => println(e ~ \"never triggered\")"]]], ["pos", [["column", i32:20], ["line", i32:1]]]]
```
The catch surrounding the function call site, not the definition site, is the
one triggered.
### Try Catch Block Value
The try catch block always evaluates to the last value inside the try catch,
never to the value of the catch block. An error being raised to try catch does
not stop the execution of nodes in the try catch.
## Checked Errors
Graphix function types are annotated by the type of error they might raise. In
most cases this is automatic, but for some higher order functions it may be
necessary to specify it explicitly. For example array map has type
`fn(Array<'a>, fn('a) -> 'b throws 'e) -> Array<'b> throws 'e` indicating that
while the map function itself does not throw any errors, it will throw any
errors the function passed to it throws. This is all in the service of being
able to statically check the type of thrown errors, for example,
```graphix
let a = [0, 1, 2, 3];
try a[0]? + a[1]?
catch(e) => select (e.0).error {
`ArithError(s) => println("arithmetic operation error [s]"),
`ArrayIndexError(s) => println("array index error [s]")
}
```
There are two types of errors that can happen in this example, and the compiler
knows that. If you were to omit one of them, then the example would not compile.
Suppose we remove the pattern for ArrayIndexError, we would get,
```
Error: in file "test.gx"
Caused by:
0: at: line: 3, column: 13, in: select (e.0).error {`ArithError(s) => ..
1: missing match cases type mismatch `ArithError('_1897: string) does not contain '_1895: [`ArithError(string), `ArrayIndexError(string)]
```
You'll recognize that this is just the normal select exhaustiveness checking at
work. Since errors are just normal types, the important point is the compiler
knows the type of every error at compile time, everything else flows from there.
## Unhandled Errors
By default when evaluating a file, the compiler will print a warning whenever an
error raised by `?` is not handled explicitly by a try catch block. Arithmetic
errors such as overflow do not generate this warning by default. Using `-W`
flags you can change the compilers behavior in this respect.
## The $ Operator, aka Or Never
The `$` operator goes in the same position as `?`, and is best described as "or
never". If the expression on it's left is a non error, then `$` doesn't do
anything, otherwise it logs the error at the `warn!` log level and returns
nothing. This is a concise way of writing,
```graphix
select might_fail(1, 2, 3) {
error as _ => never(),
v => v
}
```
can instead be written as,
```graphix
might_fail(1, 2, 3)$
```
The `$` operator logs errors rather than silently discarding them, making it
easier to debug issues while still allowing execution to continue.