Contents | < Browse | Browse >
13B. using the Raise() function
There are many ways to actually "raise" an exception, the simplest
is through the function Raise():


the exception ID is simply a constant that defines the type of
exception, and is used by handlers to determine what went wrong.

ENUM NOMEM,NOFILE  /* and others */

  DEF mem
  IF (mem:=New(10))=NIL THEN Raise(NOMEM)
  SELECT exception
      WriteF('No memory!\n')
    /* ... and others */

PROC myfunc()
  DEF mem
  IF (mem:=New(10))=NIL THEN Raise(NOMEM)

The "exception" variable in the handler always contains the value of
the argument to the Raise() call that invoked it.
In both New() cases, the Raise() function invokes the handler of
function bla(), and then exits it correctly to the caller of bla().
If myfunc() had its own exception-handler, that one would be invoked
for the New() call in myfunc(). The scope of a handler is from the start
of the PROC in which it is defined until the EXCEPT keyword, including
all calls made from there.

This has three consequences:
A. handlers are organized in a recursive fashion, and which handler is
   actually invoked is dependant on which function calls which at runtime;
B. if an exception is raised within a handler, the handler of a lower
   level is invoked. This characteristic of handlers may be used
   to implement complex recursive resource allocation schemes with
   great ease, as we'll see shortly.
C. If an exception is raised on a level where no lower-level handler
   is available (or in a program that hasn't got any handlers at all),
   the program is terminated. (i.e: Raise(x) has the same effect as

other functions:


same as Raise(), only now it takes an arbitrary value with it. in
a handler one can then scrutinize this value with the variable


has no args. simply does a Throw() on the current exception value,
IFF it is <>0.