# Exceptions

Exceptions in Basic Storm are thrown using the `throw` keyword. It accepts an arbitrary expression that is evaluated to the exception object to be thrown. It typically looks as follows:

    throw RuntimeError("Something went wrong!");

As noted in the storm reference, all exceptions must inherit (either directly or indirectly) from the `core:Exception` class. As such, new exceptions can be defined in Basic Storm, just like a regular class:

    class MyException extends Exception {
        private Str msg;

        init(Str message) {
            init { msg = message; }
            // Save the stack trace of the current thread in the exception.
            // This is optional (as it is an expensive operation), and will
            // cause '.toS' to output the stack trace.
            saveTrace();
        }

        protected void message(StrBuf to) : override {
            to << "My error: " << msg;
        }
    }

As we can see, the implementation calls `saveTrace` to store a stack trace in the exception. This is not done automatically, as collecting stack traces is a fairly expensive operation. If the stack trace is not interesting, this step can be omitted.

Furthermore, to generate a descriptive message, the exception class overrides `message(StrBuf)` rather than `toS(StrBuf)`. This is to make it possible to extract only the message (without the stack trace) by calling `message()`. The `toS` implementation will include the stack trace if it is present.

Exceptions are caught using a `try` block:

    try {
        throw MyException("Test");
    } catch (MyException e) {
        print("My exception: ${e}");
    } catch (Exception e) {
        print("Generic exception: ${e}");
    }

The code inside the `try` block is executed as normal. However, if an exception is thrown inside the block, execution is redirected to one of the `catch` blocks. The system searches the call stack from the `throw` block and upwards until a suitable `catch` block is found. If multiple `catch` blocks are present, then they are searched from top to bottom. The example above would thus print `"My exception: ..."` since the `MyException` handler is before the `Exception` handler. As illustrated below, `catch` blocks closer to the throw site have priority:

    void main() {
        try {
            a();
            print("OK!");
        } catch (MyException e) {
            print("My exception: ${e}");
        } catch (Exception e) {
            print("Generic exception: ${e}");
        }
    }

    void a() {
        try {
            b();
            print("A OK!");
        } catch (Exception e) {
            print("Generic exception in a: ${e}");
        }
    }

    void b() {
        throw MyException("Test");
    }

This example will print two lines. The first contains `Generic exception in a: ...` and the second contains `OK!`. This means that the general `catch` block inside `a` takes precedence over the specific one in `main` since it is closer to the site where the exception was thrown.

It is possible to omit the variable name (`e` in this case) if the code does not need to inspect the caught exception.

It is of course possible to re-throw the caught exception in the handler by using the `throw` keyword. Since all exceptions are classes, they are handled by reference, and there is therefore no need for a special form of the `throw` keyword for this situation.