Error Handling Statements

Magma has facilities for both reporting and handling errors. Errors can arise in a variety of circumstances within Magma's internal code (due to, for instance, incorrect usage of a function, or the unexpected failure of an algorithm). Magma allows the user to raise errors in their own code, as well as catch many kinds of errors.

Contents

The Error Objects

All errors in Magma are of type Err. Error objects not only include a description of the error, but also information relating to the location at which the error was raised, and whether the error was a user error, or a system error.

Error(x) : Any -> Err
Constructs an error object with user information given by x, which can be of any type. The object x is stored in the Object attributed of the constructed error object, and the Type attribute of the object is set to "ErrUser". The remaining attributes are uninitialized until the error is raised by an error statement; at that point they are initialized with the appropriate positional information.
e`Position : Err -> MonStgElt
Stores the position at which the error object e was raised. If the error object has not yet been raised, the attribute is undefined.
e`Traceback : Err -> MonStgElt
Stores the stack traceback giving the position at which the error object e was raised. If the error object has not yet been raised, the attribute is undefined.
e`Object : Err -> Any
Stores the user defined error information for the error. If the error is a system error, then this will be a string giving a textual description of the error.
e`Type : Err -> MonStgElt
Stores the type of the error. Currently, there are only two types of errors in Magma: "Err" denotes a system error, and "ErrUser" denotes an error raised by the user.

Error Checking and Assertions

error expression, ..., expression;
Raises an error, with the error information being the printed value of the expressions. This statement is useful, for example, when an illegal value of an argument is passed to a function.
error if boolexpr, expression, ..., expression;
If the given boolean expression evaluates to true, then raises an error, with the error information being the printed value of the expressions. This statement is designed for checking that certain conditions must be met, etc.
assert boolexpr;
assert2 boolexpr;
assert3 boolexpr;
These assertion statements are useful to check that certain conditions are satisfied. There is an underlying Assertions flag, which is set to 1 by default.

For each statement, if the Assertions flag is less than the level specified by the statement (respectively 1, 2, 3 for the above statements), then nothing is done. Otherwise, the given boolean expression is evaluated and if the result is false, an error is raised, with the error information being an appropriate message.

It is recommended that when developing package code, assert is used for important tests (always to be tested in any mode), while assert2 is used for more expensive tests, only to be checked in the debug mode, while assert3 is be used for extremely stringent tests which are very expensive.

Thus the Assertions flag can be set to 0 for no checking at all, 1 for normal checks, 2 for debug checks and 3 for extremely stringent checking.

Catching Errors

try statements catch e statements end try : ->
The try/catch statement lets users handle raised errors. The semantics of a try/catch statement are as follows: the block of statements statements1 is executed. If no error is raised during its execution, then the block of statements statements2 is not executed; if an error is raised at any point in statements1, execution immediately transfers to statements2 (the remainder of statements1 is not executed). When transfer is controlled to the catch block, the variable named e is initialized to the error that was raised by statements1; this variable remains in scope until the end of the catch block, and can be both read from and written to. The catch block can, if necessary, reraise e, or any other error object, using an error statement.

Example State_while (H1E13)

The following example demonstrates the use of error objects, and try/catch statements.
> procedure always_fails(x)
>     error Error(x);
> end procedure;
>
> try
>     always_fails(1);
>     always_fails(2);  // we never get here
> catch e
>     print "In catch handler";
>     error "Error calling procedure with parameter: ", e`Object;
> end try;
In catch handler
Error calling procedure with parameter:  1
V2.28, 13 July 2023