Skip to content

Exceptions Tutorial

Andrew Kvapil edited this page Nov 15, 2015 · 2 revisions

Exceptions tutorial

Overview

Sheets includes a custom error handling system. Rather than just throwing a plain-old-Lua error, it uses an OOP approach as well. This is where the Exception class comes in.

An exception can be thrown in two similar ways:

-- Throw the exception XException
Exception.throw( XException( ... ) )

-- The following syntax has the same effect
Exception.throw( XException, ... )

Tracebacks

Exceptions contain what is called a 'stack traceback'. This is a list of all the bits of code (their location and line number) through which the exception had to 'travel'. An example stack traceback might look like this:

{
    "lib:27";
    "main:21";
    "Button:52";
    "Sheet:101";
}

This allows you to easily track down where the exception was thrown from, and exactly where in the program it was called from.

Catching exceptions

Since exceptions are technically not errors, you cannot handle them with pcall() or xpcall(). Instead, Exception.try() is used to emulate a try&catch statement. Its syntax in Sheets is as follows:

Exception.try (f) {
    -- Catch the exception of type XException using handler1
    Exception.catch (XException) (handler1);

    -- If the exception isn't an XException, try catching YException with handler2
    Exception.catch "YException" (handler2);

    -- If the exception didn't match any of the above, default to handler3
    Exception.default (handler3);
}

That will try to execute the function f, and if it errors, will go through the list of catches/defaults until one matches, at which point the handler of that catch will be called with the exception.

A catch will match if the exception thrown is of the same type as the one the catch was called with. A default will match any exception.

Custom exceptions

Exceptions are in fact standard classes. Creating new exception types is as easy as extending the base Exception class:

-- Create a new empty class MyCustomException that inherits behaviour from Exception
class "MyCustomException" extends "Exception"

-- The constructor for our newly created class
function MyCustomException:MyCustomException( ... )
    return self:Exception( "MyCustomException", ... )
end

You would then be able to use MyCustomException as an exception type, and throw exceptions like:

Exception.throw( MyCustomException( ... ) )

and

Exception.throw( MyCustomException, ... )

Catch handlers

Using the try&catch statement, you can control what code is executed based on the exception. For example, you might want to catch an IncorrectConstructorException and write anything else to a file. To do this, you could use:

local function saveExceptionToLogFile( exception )
    -- Open a log file in append mode and save the exception data
    local h = fs.open( "log.txt", "a" )
    h.writeLine( tostring( exception ) )
    h.close()
end

local function errorWithException( exception )
    -- Simply error with the exception data
    error( tostring( exception ), 0 )
end

-- Try running function f
Exception.try (f) {
    -- In case of an IncorrectConstructorException, call errorWithException
    Exception.catch (IncorrectConstructorException) (errorWithException);

    -- Otherwise call saveExceptionToLogFile
    Exception.default (saveExceptionToLogFile)
}

Clone this wiki locally