37

When I put on my C hat, I think that maybe idiomatic Clojure just does the simple thing and checks return values.

When I put on my Java hat (reluctantly, I must add), I think to myself that since Clojure runs on the JVM the natural way must be to use JVM exceptions.

When I put on my functional hat, I'm thinking that there must be some sort of monadic construction or threading macro that can handle errors in a composable way.

So what's the idiomatic way to handle errors in a Clojure program?

Emil Eriksson
  • 2,110
  • 1
  • 21
  • 31
  • 2
    One almost feels that the Either monad belongs in core Clojure. Simply throwing an exception, which I think is typical, feels like a throwback to the imperative way of doing things. – Mario Jun 12 '15 at 13:05

3 Answers3

21

Clojure error handling is generally JVM exception (unchecked) oriented.

Slingshot makes using exceptions more pleasant by allowing, for example, destructuring on thrown exception values.

For an alternative that allows erlang-style error handling you should look at dire. This blog post gives a good overview of the rational for dire as well as an overview of Clojure error handling mechanisms and drawbacks.

Symfrog
  • 3,398
  • 1
  • 17
  • 13
  • Original link redirects to some weird spam. Here's an archive link to the blog post: http://web.archive.org/web/20150301143918/http://michaeldrogalis.tumblr.com/post/40181639419/try-catch-complects-we-can-do-so-much-better – mskoh52 Jul 27 '20 at 17:47
  • @mskoh52 thanks, I have now also updated the link in the answer – Symfrog Jul 27 '20 at 19:32
5

For a very functional approach, have a look at cats, which would correspond to "some kind of monadic construction" :

Category Theory and Algebraic abstractions for Clojure and ClojureScript. http://funcool.github.io/cats/latest/

Example taken from their documentation :

(require '[cats.core :as m])
(require '[cats.monad.maybe :as maybe])

(m/mappend (maybe/just [1 2 3])
           (maybe/nothing)
           (maybe/just [4 5 6])
           (maybe/nothing))

You can see that nothing is somewhat equivalent to nil, except you don't have to check anything manually.

nha
  • 17,623
  • 13
  • 87
  • 133
  • As a Haskeller I favor the `Maybe` monad approach by faaaar, but I don't think it's idiomatic Clojure. – MasterMastic Mar 12 '16 at 05:43
  • I only played in the repl with cats but I know some people use it in production. There is also https://github.com/uncomplicate/fluokitten/ and maybe even https://github.com/bwo/monads but there are lots of error handling libraries out there (dire and slingshot for instance) so this definitely feels like something that could be improved in the core language. – nha Mar 12 '16 at 07:33
0

The official means for error handling in Clojure is exceptions, since it comes with the JVM. However, functions are not referentially transparent when they throw exceptions and this property is not composable either. Exceptions are not functional.

Many people have tried out alternative/monadic error handling in different styles in Clojure. I have created Promenade https://github.com/kumarshantanu/promenade for this purpose and have had good experience using it.

Shantanu Kumar
  • 1,240
  • 1
  • 12
  • 14