Sophie

Sophie

distrib > Mandriva > 8.1 > i586 > by-pkgid > 700475c8ae73fb4d57b6df4485c29e1c > files > 174

slang-doc-1.4.4-2mdk.i586.rpm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<HTML>
<HEAD>
 <META NAME="GENERATOR" CONTENT="SGML-Tools 1.0.9">
 <TITLE> A Guide to the S-Lang Language: Error Handling</TITLE>
 <LINK HREF="slang-15.html" REL=next>
 <LINK HREF="slang-13.html" REL=previous>
 <LINK HREF="slang.html#toc14" REL=contents>
</HEAD>
<BODY>
<A HREF="slang-15.html">Next</A>
<A HREF="slang-13.html">Previous</A>
<A HREF="slang.html#toc14">Contents</A>
<HR>
<H2><A NAME="s14">14. Error Handling</A></H2>

<P> 
<P>Many intrinsic functions signal errors in the event of failure.
User defined functions may also generate an error condition via the
<CODE>error</CODE> function.  Depending upon the severity of the error, it
can be caught and cleared using a construct called an
<EM>error-block</EM>.
<P>
<H2><A NAME="ss14.1">14.1 Error-Blocks</A>
</H2>

<P>
<P>When the interpreter encounters a recoverable run-time error, it
will return to top-level by <EM>unwinding</EM> its function call
stack.  Any error-blocks that it encounters as part of this
unwinding process will get executed.  Errors such as syntax errors
and memory allocation errors are not recoverable, and error-blocks
will not get executed when such errors are encountered.
<P>An error-block is defined using the syntax
<BLOCKQUOTE><CODE>
<PRE>
       ERROR_BLOCK { statement-list }
</PRE>
</CODE></BLOCKQUOTE>

where <EM>statement-list</EM> represents a list of statements that
comprise the error-block.  A simple example of an error-block is
<BLOCKQUOTE><CODE>
<PRE>
       define simple (a)
       {
          ERROR_BLOCK { message ("error-block executed"); }
          if (a) error ("Triggering Error");
          message ("hello");
       }
</PRE>
</CODE></BLOCKQUOTE>

Executing this function via <CODE>simple(0)</CODE> will result in the
message <CODE>"hello"</CODE>.  However, calling it using <CODE>simple(1)</CODE>
will generate an error that will be caught, but not cleared, by
the error-block and the <CODE>"error-block executed"</CODE> message will
result.
<P>Error-blocks are never executed unless triggered by an error.  The
only exception to this is when the user explicitly indicates that
the error-block in scope should execute.  This is indicated by the
special keyword <CODE>EXECUTE_ERROR_BLOCK</CODE>.  For example,
<CODE>simple</CODE> could be recoded as
<BLOCKQUOTE><CODE>
<PRE>
       define simple (a)
       {
          variable err_string = "error-block executed";
          ERROR_BLOCK { message (err_string); }
          if (a) error ("Triggering Error");
          err_string = "hello";
          EXECUTE_ERROR_BLOCK;
       }
</PRE>
</CODE></BLOCKQUOTE>

Please note that <CODE>EXECUTE_ERROR_BLOCK</CODE> does not initiate an
error condition; it simply causes the error-block to be executed
and control will pass onto the next statement following the
<CODE>EXECUTE_ERROR_BLOCK</CODE> statement.
<P>
<H2><A NAME="ss14.2">14.2 Clearing Errors</A>
</H2>

<P>
<P>Once an error has been caught by an error-block, the error can be cleared
by the <CODE>_clear_error</CODE> function.  After the error has been cleared,
execution will resume at the next statement at the level of the error block
following the statement that generated the error.  For example, consider:
<BLOCKQUOTE><CODE>
<PRE>
       define make_error ()
       {
           error ("Error condition created.");
           message ("This statement is not executed.");
       }

       define test ()
       {
           ERROR_BLOCK
             {
                _clear_error ();
             }
           make_error ();
           message ("error cleared.");
       }
</PRE>
</CODE></BLOCKQUOTE>

Calling <CODE>test</CODE> will trigger an error in the <CODE>make_error</CODE>
function, but will get cleared in the <CODE>test</CODE> function.  The
call-stack will unwind from <CODE>make_error</CODE> back into <CODE>test</CODE>
where the error-block will get executed.  As a result, execution
resumes after the statement that makes the call to <CODE>make_error</CODE>
since this statement is at the same level as the error-block that
cleared the error.
<P>Here is another example that illustrates how multiple error-blocks
work:
<BLOCKQUOTE><CODE>
<PRE>
       define example ()
       {
          variable n = 0, s = "";
          variable str;

          ERROR_BLOCK {
              str = sprintf ("s=%s,n=%d", s, n);
              _clear_error ();
          }

          forever
            {
              ERROR_BLOCK {
               s += "0";
               _clear_error ();
              }

              if (n == 0) error ("");

              ERROR_BLOCK {
               s += "1";
              }

              if (n == 1) error ("");
              n++;
            }
          return str;
       }
</PRE>
</CODE></BLOCKQUOTE>

Here, three error-blocks have been declared.  One has been declared
outside the <CODE>forever</CODE> loop and the other two have been declared
inside the <CODE>forever</CODE> loop.  Each time through the loop, the variable
<CODE>n</CODE> is incremented and a different error-block is triggered.  The
error-block that gets triggered is the last one encountered, since
that will be the one in scope.  On the first time through the loop,
<CODE>n</CODE> will be zero and the first error-block in the loop will get
executed.  This error block clears the error and execution resumes
following the <CODE>if</CODE> statement that triggered the error. The
variable <CODE>n</CODE> will get incremented to <CODE>1</CODE> and, on the
second cycle through the loop the second <CODE>if</CODE> statement
will trigger an error causing the second error-block to execute.
This time, the error is not cleared and the call-stack unwinds out
of the <CODE>forever</CODE> loop, at which point the error-block outside
the loop is in scope, causing it to execute. This error-block
prints out the values of the variables <CODE>s</CODE> and <CODE>n</CODE>.  It
will clear the error and execution resumes on the statement
<EM>following</EM> the <CODE>forever</CODE> loop.  The result of this
complicated series of events is that the function will return the
string <CODE>"s=01,n=1"</CODE>. 
<P>
<P>
<HR>
<A HREF="slang-15.html">Next</A>
<A HREF="slang-13.html">Previous</A>
<A HREF="slang.html#toc14">Contents</A>
</BODY>
</HTML>