Skip to content
FutureBlitz

    Install

    Guide

    Errors

    Checked errors with Throws, Try and Catch, Finally and Defer, and panics with stack traces.

    FutureBlitz has two kinds of failure. An error is something a working program meets: a file that isn’t there, a save that won’t parse, a server that doesn’t answer. It’s an object of a Class extending Error, thrown and caught, and the compiler checks that each one is handled. A panic is a bug: an index out of range, overflow in a debug build, an Assert that fails. It ends the program with a stack trace.

    Throws is checked

    A Function lists what it can throw. A caller either catches it, passes it on with Try and its own Throws, or turns it into Null with Try?. Forgetting is a compile error.

    Import std.core
    
    Class SaveError Extends Error
    End Class
    
    Class CorruptSave Extends SaveError
    End Class
    
    Function ReadSlot(slot: Int): String Throws SaveError
        If slot > 3 Then Throw SaveError("there are 3 slots, not {slot}")
        If slot == 2 Then Throw CorruptSave("slot 2's checksum doesn't match")
        Return "slot {slot}: level 4"
    End Function
    
    Function Resume(slot: Int): String Throws SaveError
        Local save = Try ReadSlot(slot)       // passes a SaveError on
        Return "continuing from {save}"
    End Function
    
    For slot In [1, 2, 5]
        Try
            Print(Try Resume(slot))
        Catch e As CorruptSave
            Print("corrupt: {e.Message}")
        Catch e As SaveError
            Print("no save: {e.Message}")
        End Try
    End For
    
    Print(Try? ReadSlot(9) ?? "no slot 9")
    Output
    continuing from slot 1: level 4
    corrupt: slot 2's checksum doesn't match
    no save: there are 3 slots, not 5
    no slot 9

    std’s errors each extend Error too, one Class for each area: IOError, ParseError, NetError, DatabaseError, and the others, each with a Kind that says what went wrong.

    Finally and Defer

    A Finally block runs however its Try ends. Defer runs a statement as its block ends, so cleanup goes right beside what it cleans up.

    Import std.core
    
    Function Process(fail: Bool) Throws Error
        Print("lock the save folder")
        Defer Print("unlock the save folder")
        If fail Then Throw Error("disk full")
        Print("write the save")
    End Function
    
    Try
        Try Process(False)
        Try Process(True)
    Catch e As Error
        Print("failed: {e.Message}")
    End Try
    Output
    lock the save folder
    write the save
    unlock the save folder
    lock the save folder
    unlock the save folder
    failed: disk full

    Panics and stack traces

    A panic prints what went wrong, where, and the calls that led there, by FutureBlitz’s own names, files, and lines, from a table fb writes into every executable, so a release build’s crash names its lines with no debug files shipped. The program exits with code 101.

    Import std.core
    
    Class Inventory
        Field items: String[] = []
    
        Method Take(index: Int): String => items[index]
    End Class
    
    Function Equip(inventory: Inventory, slot: Int)
        Print("equip {inventory.Take(slot)}")
    End Function
    
    Local bag = Inventory()
    bag.items.Add("lamp")
    Equip(bag, 0)
    Equip(bag, 3)
    Output
    equip lamp
    panic: index 3 is out of range for 1 element at main.fb:6:40
        at Inventory.Take (main.fb:6)
        at Equip (main.fb:10)
        at top-level code (main.fb:16)

    Assert(condition) and Assert(condition, "message") panic when the condition is false; Panic("message") panics outright; Todo() marks what isn’t written yet. Spec chapter 09 has the rest, Tasks’ errors among them.

    Report an issue with this page or with FutureBlitz on GitHub.