<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>