SYS-EXCEPTION(2) SYS-EXCEPTION(2)
NAME
Exception, raise, rescue, rescued, unrescue - exception
handling
SYNOPSIS
include "sys.m";
sys := load Sys Sys->PATH;
Exception: adt
{
name: string; # name of exception
mod: string; # module
pc: int; # program counter
};
raise: fn(s: string);
rescue: fn(s: string, e: ref Exception): int;
rescued: fn(flag: int, s: string);
unrescue: fn();
DESCRIPTION
These functions provide exception handling in Limbo.
Exception communicates the nature of the exception.
Exception.pc is the virtual machine program counter at the
point of the raised exception, relative to the start of the
module.
Raise throws an exception with the name s, and sets the
error string for sys-print(2) (the value of the format %r)
to s.
Rescue installs a rescue block for exceptions matched by s.
If a matching exception occurs, rescue will return
Sys->EXCEPTION; otherwise it returns Sys->HANDLER. S
matches an exception name when the two are equal, or s is a
string (the prefix) followed by *, which matches any excep-
tion name starting with the same prefix. In particular, "*"
matches all exceptions. Rescue blocks can only handle
exceptions that are raised in the same thread. If an excep-
tion needs to be handled in a spawned thread, a rescue block
must be installed there.
if(sys->rescue("fail:*", e) == Sys->EXCEPTION) {
# exception handling code ...
sys->rescued(Sys->EXIT, nil);
}
Rescued tells the system what to do after an exception has
been handled, as specified by flag:
Page 1 Plan 9 (printed 10/25/25)
SYS-EXCEPTION(2) SYS-EXCEPTION(2)
ACTIVE Leave the handler installed; execution continues.
RAISE Re-raise this exception or raise a different one.
If s is nil, the current exception is re-raised;
otherwise, exception s is raised instead.
EXIT The thread exits.
ONCE Remove the handler; execution continues. For exam-
ple:
if(sys->rescue("an exception", e) == Sys->HANDLER) {
# normal execution code here
} else {
# handler code here
sys->rescued(Sys->ONCE, nil); # removes the handler
}
Unrescue removes the most recently installed handler and
continues execution.
EXAMPLES
The first example removes the handler if normal execution
completes:
if(sys->rescue("an exception", e) == Sys->HANDLER) {
# normal execution code here
sys->unrescue();
} else {
# exception handling code here
}
The next example is a complete program that demonstrates the
behaviour of exception handling by executing both the normal
execution code and the handler code.
implement Excep;
include "sys.m";
sys: Sys;
include "draw.m";
Excep: module
{
init: fn(ctxt: ref Draw->Context, argv: list of string);
};
init(ctxt: ref Draw->Context, argv: list of string)
{
sys = load Sys Sys->PATH;
e := ref sys->Exception;
if(sys->rescue("an exception", e) == Sys->EXCEPTION) {
sys->print("rescue: exception\n");
sys->print("e.name = %s\ne.mod = %s\ne.pc = %d\n",
e.name, e.mod, e.pc);
Page 2 Plan 9 (printed 10/25/25)
SYS-EXCEPTION(2) SYS-EXCEPTION(2)
sys->rescued(Sys->ONCE, nil);
} else {
sys->print("rescue: normal execution\n");
sys->raise("an exception");
}
sys->print("raise: %r\n");
sys->raise("nasty thing"); # won't be handled
}
SEE ALSO
sh(1), prog(3)
Page 3 Plan 9 (printed 10/25/25)