Users › 08 Exceptions

Exceptions

Throw and catch exceptions, understand finally, and write your own exception classes.

1. What an exception is

An exception is any object that implements the _LANG.Exception interface. That interface has default methods, so an implementer only needs the three bindings:

%interface Exception
    String getName() { return "Exception" }
    String toString() { return "" }
    int toInt() { return -1 }

Two exceptions are built in and thrown by the runtime: IndexOutOfBoundsException (fields index and length) and DivideByZeroException.

2. throw, try, catch, finally

try {
    int[] a = new int[3]
    int x = a[9]                    // IndexOutOfBoundsException
} catch (IndexOutOfBoundsException e) {
    // matched by class
} catch (Exception e) {
    // matched by interface
} finally {
    // always runs
}

3. Custom exceptions

%class com.example.MyError implements Exception
    String _msg
    int _code

    void ___init(String msg, int code) {
        this._msg = msg
        this._code = code
    }

    String getName() Exception@getName {
        return "MyError"
    }

    String toString() Exception@toString {
        return "MyError: " + this._msg + ":" + this._code
    }

    int toInt() Exception@toInt {
        return -2
    }

The task-list example throws CapacityException when a bounded list is full; the main program catches it and prints the message.

4. throws declarations

int parse(String s) throws (com.example.ParseError) {
    ...
}

throws goes after the interface bindings. It is documentation only: the compiler does not enforce it.

5. Uncaught exceptions

If no catch matches, the exception reaches the top of the thread. The runtime prints uncaught exception: <class name> and the thread ends; for the main thread the process exits with code 1. A worker thread dying this way does not stop the other threads (chapter 10).

6. Try it

%simple com.example.exc.Demo implements Main
    #import Std
    int run(int argc, String[] argv) Main@run {
        int r = 0
        try {
            Std.print("try\n")
            int[] a = new int[2]
            int x = a[5]
            Std.print("not reached\n")
        } catch (IndexOutOfBoundsException e) {
            Std.print("catch: ", e.getName(), " index=", e.index, " length=", e.length, "\n")
            r = 1
        } finally {
            Std.print("finally\n")
        }
        try {
            int z = 1 / (argc - argc)
            Std.print("z=", z, "\n")
        } catch (DivideByZeroException e) {
            Std.print("div: ", e.getName(), "\n")
            r = r + 1
        }
        return r == 2 ? 0 : 1
    }
try
catch: IndexOutOfBoundsException index=5 length=2
finally
div: DivideByZeroException