9

How does one deal with exceptions that could occur in the bindings or body of a let statement using the same finally block? Ex:

(let [connections (create-connections)] 
  (dostuff)
  (close connections))

If (create-connections) or (dostuff) fails, I want to (close connections). Some options:

Option 1:

(try     
  (let [connections (create-connections)] 
    (dostuff))
  (finally (close connections))

This obviously doesn't work though since connections is not in scope in the finally block.

Option 2:

(let [connections (create-connections)]
  (try
    (dostuff)
    (finally (close connections)))

This option only catches exceptions that occur in the (destuff) call though and not those that occur in (create-connections).

Option 3:

(let [connections (try 
                    (create-connections)
                    (finally (close connections)))]
  (try
    (dostuff)
    (finally (close connections)))

This also doesn't work since connections is not in scope for the finally statement inside the let binding.

So what's the best way of dealing with this?

Qix - MONICA WAS MISTREATED
  • 14,451
  • 16
  • 82
  • 145
Josh
  • 875
  • 1
  • 13
  • 25
  • 2
    How could you possible close connections that you failed to create? It just doesn't make sense. – amalloy Dec 03 '13 at 00:16
  • Here's an interesting discussion: https://groups.google.com/forum/#!topic/clojure/hsh-H8SxNHw - especially this comment: https://groups.google.com/d/msg/clojure/hsh-H8SxNHw/Hm0Nh2MsZGIJ – Juraj Martinka Dec 28 '18 at 17:15

1 Answers1

11

The built in with-open works on anything you can call .close on, so the normal approach is to use something like:

(with-open [connections (create-connections)] 
    (do-stuff connections))

and handle errors opening connections within the code that failed to open them. If create-connections fails to open one of the connections then perhaps a try ... finally block within create-connections is a cleaner place to handle that sort of error condition.

Arthur Ulfeldt
  • 90,827
  • 27
  • 201
  • 284
  • I think you're right about handling connection open failures within create-connections. Failures while creating a connection is really a separate concern from failures that occur while doing stuff, therefore the handling can be separate. Good call. – Josh Dec 02 '13 at 19:27
  • 5
    Its unfortunate you accepted this answer, as it does not address the more general question you bring up, but only the specific example you gave. – Didier A. Sep 30 '17 at 20:42