santiagocabrera96

santiagocabrera96

Programming Clojure, Fourth Edition: ex-info should include the cause. (p. 224)

In page 224, the following code is suggested.

(defn load-resource [path]
  (try
    (if (forbidden? path)
      (throw (ex-info "Forbidden resource"
                      {:status 403 :resource path}))
      (slurp path))
    (catch java.io.FileNotFoundException e
      (throw (ex-info "Missing resource"
                      {:status 404 :resource path})))
    (catch java.io.IOException e
      (throw (ex-info "Server error"
                      {:status 500 :resource path})))))

I’ve seen this in practice a lot and not including the cause when catching an exception generates headaches to debug later.

I’d suggest to do a bit of explanation of adding the cause exception to the ex info in the catch clauses like this:

(defn load-resource [path]
  (try
    (if (forbidden? path)
      (throw (ex-info "Forbidden resource"
                      {:status 403 :resource path}))
      (slurp path))
    (catch java.io.FileNotFoundException e
      (throw (ex-info "Missing resource"
                      {:status 404 :resource path}
                      e)))
    (catch java.io.IOException e
      (throw (ex-info "Server error"
                      {:status 500 :resource path}
                      e)))))

This is really useful for me to add context to exceptions that might happen in calling functions on sequences to understand what element failed.

Here’s a dummy example where I can call a function that might throw, and I would want more context on where it failed, and I can add context to the existing ex-info.

(defn randomly-fails []
  (when (> (rand-int 10) 8)
    (throw (ex-info "Randomly failed!" {}))))
(run! #(try (randomly-fails)
            (catch clojure.lang.ExceptionInfo e
              (throw (ex-info (ex-message e)
                              (assoc (ex-data e) :n %)
                              e))))
      (range 100))
=> #'examples.interop/randomly-fails
Execution error (ExceptionInfo) at examples.interop/randomly-fails (form-init16509100671821839256.clj:3).
Randomly failed!
*e
=>
#error
{:cause "Randomly failed!",
 :data {},
 :via [{:type clojure.lang.ExceptionInfo,
        :message "Randomly failed!",
        :data {:n 7},
        :at [examples.interop$eval2303$fn__2304 invoke "form-init16509100671821839256.clj" 6]}
       {:type clojure.lang.ExceptionInfo,
        :message "Randomly failed!",
        :data {},
        :at [examples.interop$randomly_fails invokeStatic "form-init16509100671821839256.clj" 3]}],

Where Next?

Popular Pragmatic Bookshelf topics Top

jon
Some minor things in the paper edition that says “3 2020” on the title page verso, not mentioned in the book’s errata online: p. 186 But...
New
lirux
Hi Jamis, I think there’s an issue with a test on chapter 6. I own the ebook, version P1.0 Feb. 2019. This test doesn’t pass for me: ...
New
JohnS
I can’t setup the Rails source code. This happens in a working directory containing multiple (postgres) Rails apps. With: ruby-3.0.0 s...
New
herminiotorres
Hi! I know not the intentions behind this narrative when called, on page XI: mount() |> handle_event() |> render() but the correc...
New
swlaschin
The book has the same “Problem space/Solution space” diagram on page 18 as is on page 17. The correct Problem/Solution space diagrams ar...
New
brunogirin
When trying to run tox in parallel as explained on page 151, I got the following error: tox: error: argument -p/–parallel: expected one...
New
creminology
Skimming ahead, much of the following is explained in Chapter 3, but new readers (like me!) will hit a roadblock in Chapter 2 with their ...
New
Henrai
Hi, I’m working on the Chapter 8 of the book. After I add add the point_offset, I’m still able to see acne: In the image above, I re...
New
dtonhofer
@parrt In the context of Chapter 4.3, the grammar Java.g4, meant to parse Java 6 compilation units, no longer passes ANTLR (currently 4....
New
ggerico
I got this error when executing the plot files on macOS Ventura 13.0.1 with Python 3.10.8 and matplotlib 3.6.1: programming_ML/code/03_...
New

Other popular topics Top

PragmaticBookshelf
Machine learning can be intimidating, with its reliance on math and algorithms that most programmers don't encounter in their regular wor...
New
PragmaticBookshelf
Write Elixir tests that you can be proud of. Dive into Elixir’s test philosophy and gain mastery over the terminology and concepts that u...
New
AstonJ
You might be thinking we should just ask who’s not using VSCode :joy: however there are some new additions in the space that might give V...
New
AstonJ
I’ve been hearing quite a lot of comments relating to the sound of a keyboard, with one of the most desirable of these called ‘thock’, he...
New
New
AstonJ
Just done a fresh install of macOS Big Sur and on installing Erlang I am getting: asdf install erlang 23.1.2 Configure failed. checking ...
New
PragmaticBookshelf
Use WebRTC to build web applications that stream media and data in real time directly from one user to another, all in the browser. ...
New
mafinar
This is going to be a long an frequently posted thread. While talking to a friend of mine who has taken data structure and algorithm cou...
New
PragmaticBookshelf
Author Spotlight Rebecca Skinner @RebeccaSkinner Welcome to our latest author spotlight, where we sit down with Rebecca Skinner, auth...
New
husaindevelop
Inside our android webview app, we are trying to paste the copied content from another app eg (notes) using navigator.clipboard.readtext ...
New

Sub Categories: