It is often useful to be able to **catch** an error that an expression
raises, to keep the error from aborting the whole task, and to keep on running
as if the expression had returned some other value normally. The following
expression accomplishes this:

`expr-1!codes=>expr-2'

**Note:** the open- and close-quotation marks in the previous line are
really part of the syntax; you must actually type them as part of your MOO
program for this kind of expression.

The `codes` part is either the keyword `ANY`

or else a
comma-separated list of expressions, just like an argument list. As in an
argument list, the splicing operator (``@'`) can be used here. The
`=> `

part of the error-catching expression is optional.
`expr-2`

First, the `codes` part is evaluated, yielding a list of error codes that
should be caught if they're raised; if `codes` is `ANY`

, then it is
equivalent to the list of all possible MOO values.

Next, `expr-1` is evaluated. If it evaluates normally, without raising an
error, then its value becomes the value of the entire error-catching
expression. If evaluating `expr-1` results in an error being raised, then
call that error `E`. If `E` is in the list resulting from evaluating
`codes`, then `E` is considered **caught** by this error-catching
expression. In such a case, if `expr-2` was given, it is evaluated to get
the outcome of the entire error-catching expression; if `expr-2` was
omitted, then `E` becomes the value of the entire expression. If `E`
is *not* in the list resulting from `codes`, then this expression does
not catch the error at all and it continues to be raised, possibly to be caught
by some piece of code either surrounding this expression or higher up on the
verb-call stack.

Here are some examples of the use of this kind of expression:

`x + 1 ! E_TYPE => 0'

Returns `x + 1`

if `x`

is an integer, returns `0`

if `x`

is
not an integer, and raises `E_VARNF`

if `x`

doesn't have a value.

`x.y ! E_PROPNF, E_PERM => 17'

Returns `x.y`

if that doesn't cause an error, `17`

if `x`

doesn't have a `y`

property or that property isn't readable, and raises
some other kind of error (like `E_INVIND`

) if `x.y`

does.

`1 / 0 ! ANY'

Returns `E_DIV`

.

Go to the first, previous, next, last section, table of contents.