One of the main uses of Fibers is to encapsulate and handle errors. Janet offers
no direct mechanism for try/catch like some language, and instead builds error
handling on top of Fibers. When some function throws an error, Janet creates a signal
and throws that signal in the current fiber. The signal will be propogated up the
chain of active fibers until it hits a fiber that is ready to handle the error signal.
This fiber will trap the signal and return the error from the last call to
(defn block  (print "inside block...") (error "oops")) # Pass the :e flag to trap errors (and only errors). # All other signals will be propogated up the fiber stack. (def f (fiber/new block :e)) # Get result of resuming the fiber in res. # Because the fiber f traps only errors, we know # that after resume returns, f either exited normally # (has status :dead), or threw an error (has status :error) (def res (resume f)) (if (= (fiber/status f) :error) (print "caught error: " res) (print "value returned: " res))
Janet also provides a simple macro
try to make this
a bit easier in the common case.
(try (do (print "inside block...") (error "oops") (print "will never get here")) ([err] (print "caught error: " err)))