Exception handling in Toit
Try and finally
try block in Toit is used to execute code following the
try statement as a “normal” part of the program.
finally keyword defines a block of code to run when the try block is final.
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 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
throw is implemented as a function that takes a value to be
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
--traceargument 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. The
traceblock is passed an argument that is the thrown object.
--unwindargument takes a boolean or a block that evaluates to a boolean. It determines whether the execution stack continues to unwind after the catch. By default
false. If the block evaluates to
truethen the exception will continue to unwind the call stack as if the catch were not present. The
unwindblock 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"