The Sway Reference Manual/Exceptions

Exceptions occur when the interpreter detects an error in the code. These errors could be syntax errors or semantic errors. You've seen the aftermath of exceptions before: undefined variable exceptions, divide by zero exceptions, and so on.

When an exception is generated, it is said to be raised or thrown. Unless the exception is caught, it terminates processing of the current function call, then propagates upward, terminating the processing of the function that made the call, and so on and so on.

Unless the exception is caught (see the next section), the exception eventually terminates the Sway interpreter if executing a file. If Sway is running interactively, the processing terminates up to, but not including, the prompt-read-eval loop (the one with the sway> and more> prompts).

Handling exceptions
It is possible to stop the propagation of an exception by using the catch function. The sole argument to catch is an expression that may generate an exception. The catch function evaluates its argument and, if no exception was raised, returns the value of the evaluated expression. If an exception was raised, catch converts the exception into an error object.

Here is a typical use of catch:

var x = catch(process(a,b)); if (x is :ERROR && x . type == :mathError) {       x = 0; }   else if (x is :ERROR) {       throw(x); }   ...

Note that if you catch an exception but it turns out you don't wish to handle it, you can rethrow it with the throw function.

Throwing exceptions
You can generate your own exceptions with a different use of the throw function. This use of throw requires two arguments. These arguments can be anything, but, by convention, the first argument is a symbol and the second is a string giving more explanation concerning the error. For example, suppose you wish raise an exception if a variable is supposed to be even and it's not:

if (x % 2 == 1) {       throw(:oddValue,"x is " + x + ", it should be even."); }

Try catch blocks
If you include the basics library, you can use the 'try function, which simplifies the catching and processing of exceptions. Here is a version of the typical usage shown previously:

var error; ...   try (error) {       x = process(a,b); }   else if (error . type ==  :mathError) {       x = 0; }   else {       throw(error); }   ...

The try function requires that a variable be passed as the first argument; it will set this variable to the caught exception, should an exception occur.

Returns are exceptions
The return function generates a special exception of type :return, so the expression

return x + y; is equivalent to:

throw(:return,x + y);

Since a return is ultimately an exception, encountering a return causes an immediate end to the processing of the body of a function.

This exception, however, is caught by the part of the interpreter that sets up the function call and is not allowed to propagate further.