Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Throwing and catching exceptions

jank integrates tightly into C++’s exception model. C++ allows values of any type to be thrown, caught, and rethrown. So does jank.

Throwing and catching jank objects

When you throw a value from jank, regardless of its type, the value will be type-erased into an object_ref. It doesn’t matter if you throw a keyword or a hash map or a string, or any other jank runtime object, you catch it as an object_ref. For example:

(defn -main [& args]
  (try
    (throw :ok!)
    (catch cpp/jank.runtime.object_ref e
      (println :caught e))))

Throwing and catching native values

Many C++ libraries will throw values which are not jank runtime objects. A very common type to throw is a class derived from std::exception. From jank, we can catch any C++ type and, just like in C++, we can catch exceptions via their base type as well.

In this example, calling .at on a std::vector, with an invalid index, will throw a std::out_of_range exception, which derives from std::exception. We can catch the exception by the base type and then rely on the virtual .what member function to get the exception message.


(let [v ((cpp/type "std::vector<int>"))]
  (try
    ; This will throw.
    (.at v #cpp 0)
    (catch cpp/std.exception e
      (println :caught (.what e)))))

Note

jank doesn’t yet support providing native values to (throw ...), but it will soon.

Also, jank doesn’t yet support the equivalent of C++’s catch all, which catches any exception type, but doesn’t provide the value. We will support this, too.