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?
The built in
with-open
works on anything you can call.close
on, so the normal approach is to use something like: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.