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

Catching Errors in Expressions

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 => expr-2 part of the error-catching expression is optional.

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.