Exception handling
Try and finally
The try
block in Toit is used to execute code following the try
statement as a “normal” part of the program.
The finally
keyword defines a block of code to run when the try block is final.
The finally
block will be executed no matter if the try block raises an error or not.
This can be useful to close objects and clean up resources.
main: connection ::= device.ConsoleConnection.open try: accelerometer := Accelerometer.start try: print "started" while true: force := movement accelerometer print "got movement: $force - moving: $(is-moving force)" sleep --ms=1000 finally: accelerometer.close finally: connection.close
Throw
The throw
keyword in Toit is used to explicitly throw an exception from a
method or any block of code. Any object can be thrown. Currently the core
libraries often throw strings containing error messages. Although it looks like
a keyword, throw
is implemented as a function that takes a value to be
thrown.
Catch
Code that may throw an exception can be wrapped in a catch
. This is
implemented as a function that takes the possibly throwing code as a block.
Catch will return the thrown object, or null
if no object was thrown.
Catch takes two optional arguments
The
--trace
argument is a boolean or a block that evaluates to a boolean. It controls whether the caught exception is reported in the console. By default the exception is not reported. Thetrace
block is passed an argument that is the thrown object.The
--unwind
argument takes a boolean or a block that evaluates to a boolean. It determines whether the execution stack continues to unwind after the catch. By defaultunwind
isfalse
. If the block evaluates totrue
then the exception will continue to unwind the call stack as if the catch were not present. Theunwind
block is passed the thrown object as an argument, which it can use to determine whether to unwind.
my-function: my-exception := catch --trace: code-that-might-throw 42 103 if my-exception: code-to-run-when-an-exception-was-thrown "foo" "bar" // Identifies exceptions that we want to catch. Every other // exception will result in a stack trace on the console and // an uncaught exception (which may nevertheless be caught // further up the call stack). is-bad thrown-object: return thrown-object != "HARMLESS_ERROR" my-other-function: exception := catch --trace=: | thrown | is-bad thrown --unwind=: | thrown | is-bad thrown: code-that-might-throw 42 103 if exception: // A harmless error was thrown. code-to-run-when-an-exception-was-thrown "foo" "bar"