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
Following the steps described in Chapter 6 of the book, I’m stuck with running the migration as described on page 84:
bundle exec sequel...
New
Hello Brian,
I have some problems with running the code in your book. I like the style of the book very much and I have learnt a lot as...
New
Hi @Margaret ,
On page VII the book tells us the example and snippets will be all using Elixir version 1.11
But on page 3 almost the en...
New
I’m under the impression that when the reader gets to page 136 (“View Data with the Database Inspector”), the code SHOULD be able to buil...
New
The test is as follows:
Scenario: Intersecting a scaled sphere with a ray
Given r ← ray(point(0, 0, -5), vector(0, 0, 1))
And s ← sphere...
New
On page 78 the following code appears:
<%= link_to ‘Destroy’, product,
class: ‘hover:underline’,
method: :delete,
data: { confirm...
New
It seems the second code snippet is missing the code to set the current_user:
current_user: Accounts.get_user_by_session_token(session["...
New
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
Hi, I’ve got a question about the implementation of PubSub when using a Phoenix.Socket.Transport behaviour rather than channels.
Before ...
New
@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
Other popular topics
My first contact with Erlang was about 2 years ago when I used RabbitMQ, which is written in Erlang, for my job. This made me curious and...
New
A few weeks ago I started using Warp a terminal written in rust. Though in it’s current state of development there are a few caveats (tab...
New
Build efficient applications that exploit the unique benefits of a pure functional language, learning from an engineer who uses Haskell t...
New
Programming Ruby is the most complete book on Ruby, covering both the language itself and the standard library as well as commonly used t...
New
zig/http.zig at 7cf2cbb33ef34c1d211135f56d30fe23b6cacd42 · ziglang/zig.
General-purpose programming language and toolchain for maintaini...
New
Develop, deploy, and debug BEAM applications using BEAMOps: a new paradigm that focuses on scalability, fault tolerance, and owning each ...
New
Get the comprehensive, insider information you need for Rails 8 with the new edition of this award-winning classic.
Sam Ruby @rubys
...
New
Node.js v22.14.0 has been released.
Link: Release 2025-02-11, Version 22.14.0 'Jod' (LTS), @aduh95 · nodejs/node · GitHub
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
Use advanced functional programming principles, practical Domain-Driven Design techniques, and production-ready Elixir code to build scal...
New
Categories:
Sub Categories:
Popular Portals
- /elixir
- /rust
- /wasm
- /ruby
- /erlang
- /phoenix
- /keyboards
- /python
- /js
- /rails
- /security
- /go
- /swift
- /vim
- /java
- /clojure
- /typescript
- /emacs
- /haskell
- /svelte
- /onivim
- /kotlin
- /react
- /c-plus-plus
- /crystal
- /tailwind
- /gleam
- /ocaml
- /elm
- /vscode
- /flutter
- /html
- /ash
- /deepseek
- /zig
- /opensuse
- /php
- /centos
- /react-native
- /scala
- /lisp
- /textmate
- /sublime-text
- /nixos
- /debian
- /deno
- /agda
- /django
- /nodejs
- /kubuntu
- /arch-linux
- /ubuntu
- /spring
- /revery
- /manjaro
- /quarkus
- /julia
- /diversity
- /lua
- /laravel









