<HTML>
<HEAD>
<!-- This HTML file has been created by texi2html 1.51
from ProgrammersManual.texinfo on 4 March 1997 -->
<TITLE>LambdaMOO Programmer's Manual - Handling Errors</TITLE>
</HEAD>
<BODY>
Go to the <A HREF="ProgrammersManual_1.html">first</A>, <A HREF="ProgrammersManual_34.html">previous</A>, <A HREF="ProgrammersManual_36.html">next</A>, <A HREF="ProgrammersManual_77.html">last</A> section, <A HREF="ProgrammersManual_toc.html">table of contents</A>.
<P><HR><P>
<H3><A NAME="SEC35" HREF="ProgrammersManual_toc.html#TOC35">Handling Errors in Statements</A></H3>
<P>
Normally, whenever a piece of MOO code raises an error, the entire task is
aborted and a message printed to the user. Often, such errors can be
anticipated in advance by the programmer and code written to deal with them in
a more graceful manner. The <CODE>try</CODE>-<CODE>except</CODE> statement allows you to
do this; the syntax is as follows:
</P>
<PRE>
try
<VAR>statements-0</VAR>
except <VAR>variable-1</VAR> (<VAR>codes-1</VAR>)
<VAR>statements-1</VAR>
except <VAR>variable-2</VAR> (<VAR>codes-2</VAR>)
<VAR>statements-2</VAR>
...
endtry
</PRE>
<P>
where the <VAR>variable</VAR>s may be omitted and each <VAR>codes</VAR> part is either
the keyword <CODE>ANY</CODE> or else a comma-separated list of expressions, just like
an argument list. As in an argument list, the splicing operator (<SAMP>`@'</SAMP>)
can be used here. There can be anywhere from 1 to 255 <CODE>except</CODE> clauses.
</P>
<P>
First, each <VAR>codes</VAR> part is evaluated, yielding a list of error codes that
should be caught if they're raised; if a <VAR>codes</VAR> is <CODE>ANY</CODE>, then it is
equivalent to the list of all possible MOO values.
</P>
<P>
Next, <VAR>statements-0</VAR> is executed; if it doesn't raise an error, then that's
all that happens for the entire <CODE>try</CODE>-<CODE>except</CODE> statement. Otherwise,
let <VAR>E</VAR> be the error it raises. From top to bottom, <VAR>E</VAR> is searched
for in the lists resulting from the various <VAR>codes</VAR> parts; if it isn't
found in any of them, then it continues to be raised, possibly to be caught by
some piece of code either surrounding this <CODE>try</CODE>-<CODE>except</CODE> statement
or higher up on the verb-call stack.
</P>
<P>
If <VAR>E</VAR> is found first in <VAR>codes-i</VAR>, then <VAR>variable-i</VAR> (if provided)
is assigned a value containing information about the error being raised and
<VAR>statements-i</VAR> is executed. The value assigned to <VAR>variable-i</VAR> is a
list of four elements:
<PRE>
{<VAR>code</VAR>, <VAR>message</VAR>, <VAR>value</VAR>, <VAR>traceback</VAR>}
</PRE>
<P>
where <VAR>code</VAR> is <VAR>E</VAR>, the error being raised, <VAR>message</VAR> and
<VAR>value</VAR> are as provided by the code that raised the error, and
<VAR>traceback</VAR> is a list like that returned by the <SAMP>`callers()'</SAMP> function,
including line numbers. The <VAR>traceback</VAR> list contains entries for every
verb from the one that raised the error through the one containing this
<CODE>try</CODE>-<CODE>except</CODE> statement.
</P>
<P>
Unless otherwise mentioned, all of the built-in errors raised by expressions,
statements, and functions provide <CODE>tostr(<VAR>code</VAR>)</CODE> as <VAR>message</VAR> and
zero as <VAR>value</VAR>.
</P>
<P>
Here's an example of the use of this kind of statement:
</P>
<PRE>
try
result = object:(command)(@arguments);
player:tell("=> ", toliteral(result));
except v (ANY)
tb = v[4];
if (length(tb) == 1)
player:tell("** Illegal command: ", v[2]);
else
top = tb[1];
tb[1..1] = {};
player:tell(top[1], ":", top[2], ", line ", top[6], ":",
v[2]);
for fr in (tb)
player:tell("... called from ", fr[1], ":", fr[2],
", line ", fr[6]);
endfor
player:tell("(End of traceback)");
endif
endtry
</PRE>
<P><HR><P>
Go to the <A HREF="ProgrammersManual_1.html">first</A>, <A HREF="ProgrammersManual_34.html">previous</A>, <A HREF="ProgrammersManual_36.html">next</A>, <A HREF="ProgrammersManual_77.html">last</A> section, <A HREF="ProgrammersManual_toc.html">table of contents</A>.
</BODY>
</HTML>