Throw statement

The throw statement is used to throw an exception. The thrown exception must be a tag (see below). Unlike traps, thrown exceptions can be caught using try-catch statements inside of Water code.

When an exception is thrown, it starts popping the call stack frame, exiting all blocks and functions, until it reaches a containing try-catch statement which catches the exception. The same exception may subsequently be rethrown in the catch statement. If an exception is not caught, and the entire call stack is exhausted, then the exception is forwarded to the embedder where the original exported Water function was called.

Tags

As noted above, the throw statement can only throw a tag value. A tag is similar to a class instance, but it is not possible to read its contents except for when it is caught as an exception.

In Water, a tag can be created by simply adding a [Tag] attribute to a class definition. When the [Tag] attribute is present, then the class may also be declared as an external export of the Wasm module, where the tag representing the class will be exported. This is useful, because for an embedder (e.g. Javascript) to be able to read an exception's fields, it needs to have access to the tag of the thrown exception.

Example

This example declares an exception type and throws it. You will see an error in the output containing all of the exception's properties. This is done by the Javascript code running these examples by checking all of the Wasm module's exports, filtering for tags, and checking if the thrown exception matches one of those tags (with<Exception>.is). Then, if a tag matches, it reads all of its properties with <Exception>.getArg.

If you remove the external export declaration from the tag definition, then the properties of the exception will no longer be shown in the console, because there is no other way of reading them.