Janet 1.15.0-2795e8a Documentation
(Other Versions: 1.13.1 1.12.2 1.11.1 1.10.1 1.9.1 1.8.1 1.7.0 1.6.0 1.5.1 1.5.0 1.4.0 1.3.1 )

Error Handling

One of the main uses of fibers is to encapsulate and handle errors. Janet offers no direct try/catch mechanism like some languages, and instead builds error handling on top of fibers. When a function throws an error, Janet creates a signal and throws that signal in the current fiber. The signal will be propagated 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 resume.

(defn block
  []
  (print "inside block...")
  (error "oops"))

# Pass the :e flag to trap errors (and only errors).
# All other signals will be propagated 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))

Two error-handling forms built on fibers

try

Janet provides a simple macro try to make error-handling a bit easier in the common case. try performs the function of a traditional try/catch block; it will execute its body and, if any error is raised, optionally bind the error and the raising fiber in its second clause.

(try
 (do
   (print "inside block...")
   (error "oops")
   (print "will never get here"))
 ([err] (print "caught error: " err)))

protect

Janet also provides the protect macro for a slightly different flavor of error-handling, converting caught errors into further expressions.

(protect
  (if (> (math/random) 0.42)
    (error "Good luck")
    "Bad luck"))