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

johnp
Running the examples in chapter 5 c under pytest 5.4.1 causes an AttributeError: ‘module’ object has no attribute ‘config’. In particula...
New
jamis
The following is cross-posted from the original Ray Tracer Challenge forum, from a post by garfieldnate. I’m cross-posting it so that the...
New
edruder
I thought that there might be interest in using the book with Rails 6.1 and Ruby 2.7.2. I’ll note what I needed to do differently here. ...
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
raul
Page 28: It implements io.ReaderAt on the store type. Sorry if it’s a dumb question but was the io.ReaderAt supposed to be io.ReadAt? ...
New
alanq
This isn’t directly about the book contents so maybe not the right forum…but in some of the code apps (e.g. turbo/06) it sends a TURBO_ST...
New
nicoatridge
Hi, I have just acquired Michael Fazio’s “Kotlin and Android Development” to learn about game programming for Android. I have a game in p...
New
taguniversalmachine
Hi, I am getting an error I cannot figure out on my test. I have what I think is the exact code from the book, other than I changed “us...
New
kolossal
Hi, I need some help, I’m new to rust and was learning through your book. but I got stuck at the last stage of distribution. Whenever I t...
New
gorkaio
root_layout: {PentoWeb.LayoutView, :root}, This results in the following following error: no “root” html template defined for PentoWeb...
New

Other popular topics Top

Devtalk
Hello Devtalk World! Please let us know a little about who you are and where you’re from :nerd_face:
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
Exadra37
I am thinking in building or buy a desktop computer for programing, both professionally and on my free time, and my choice of OS is Linux...
New
Exadra37
Please tell us what is your preferred monitor setup for programming(not gaming) and why you have chosen it. Does your monitor have eye p...
New
PragmaticBookshelf
Rust is an exciting new programming language combining the power of C with memory safety, fearless concurrency, and productivity boosters...
New
PragmaticBookshelf
Create efficient, elegant software tests in pytest, Python's most powerful testing framework. Brian Okken @brianokken Edited by Kat...
New
New
PragmaticBookshelf
Get the comprehensive, insider information you need for Rails 8 with the new edition of this award-winning classic. Sam Ruby @rubys ...
New
PragmaticBookshelf
A masterclass in the fundamentals and principles of functional programming. Minh Quang Tran The Art of Functional Programming is a ma...
New
NewsBot
Node.js v22.14.0 has been released. Link: Release 2025-02-11, Version 22.14.0 'Jod' (LTS), @aduh95 · nodejs/node · GitHub
New

Sub Categories: