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]}],
Popular Pragmatic Bookshelf topics
page 20: … protoc command…
I had to additionally run the following go get commands in order to be able to compile protobuf code using go...
New
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
page 37
ANTLRInputStream input = new ANTLRInputStream(is);
as of ANTLR 4 .8 should be:
CharStream stream = CharStreams.fromStream(i...
New
Python Testing With Pytest - Chapter 2, warnings for “unregistered custom marks”
While running the smoke tests in Chapter 2, I get these...
New
Title: Web Development with Clojure, Third Edition, vB17.0 (p9)
The create table guestbook syntax suggested doesn’t seem to be accepted ...
New
#book-python-testing-with-pytest-second-edition
Hi. Thanks for writing the book. I am just learning so this might just of been an issue ...
New
“The ProductLive.Index template calls a helper function, live_component/3, that in turn calls on the modal component. ”
Excerpt From: Br...
New
I’m not quite sure what’s going on here, but I’m unable to have to containers successfully complete the Readiness/Liveness checks. I’m im...
New
I’m a newbie to Rails 7 and have hit an issue with the bin/Dev script mentioned on pages 112-113.
Iteration A1 - Seeing the list of prod...
New
I’ve got to the end of Ch. 11, and the app runs, with all tabs displaying what they should – at first. After switching around between St...
New
Other popular topics
Algorithms and data structures are much more than abstract concepts. Mastering them enables you to write code that runs faster and more e...
New
Rust is an exciting new programming language combining the power of C with memory safety, fearless concurrency, and productivity boosters...
New
Small essay with thoughts on macOS vs. Linux:
I know @Exadra37 is just waiting around the corner to scream at me “I TOLD YOU SO!!!” but I...
New
If you get Can't find emacs in your PATH when trying to install Doom Emacs on your Mac you… just… need to install Emacs first! :lol:
bre...
New
Author Spotlight
Mike Riley
@mriley
This month, we turn the spotlight on Mike Riley, author of Portable Python Projects. Mike’s book ...
New
Build modern server-driven web applications using htmx. Whatever programming language you use, you’ll write less (and cleaner) code.
...
New
A Brief Review of the Minisforum V3 AMD Tablet.
Update: I have created an awesome-minisforum-v3 GitHub repository to list information fo...
New
Escape callback hell and ship fast, clean code that reads as smoothly as it runs. Squash bugs and stamp out memory leaks with an intuitiv...
New
Quickly turn complex problems into simple, working solutions using functional programming, safe concurrency, and the expressive tools of ...
New
Open-source implementation of the classic GTA engine now running directly in your browser. Experience the reVC technology demo on DOS.Zon...
New
Categories:
Sub Categories:
Popular Portals
- /elixir
- /rust
- /wasm
- /ruby
- /erlang
- /phoenix
- /keyboards
- /python
- /js
- /rails
- /security
- /go
- /swift
- /vim
- /java
- /clojure
- /emacs
- /haskell
- /typescript
- /svelte
- /onivim
- /kotlin
- /c-plus-plus
- /crystal
- /tailwind
- /react
- /gleam
- /ocaml
- /elm
- /vscode
- /flutter
- /html
- /ash
- /deepseek
- /zig
- /opensuse
- /centos
- /php
- /react-native
- /scala
- /lisp
- /sublime-text
- /textmate
- /nixos
- /debian
- /agda
- /deno
- /django
- /kubuntu
- /nodejs
- /arch-linux
- /spring
- /ubuntu
- /revery
- /manjaro
- /julia
- /lua
- /diversity
- /quarkus
- /markdown









