I'm not actually sure if this is an issue or a question, but it certainly was unexpected and caused problems in my existing software, so here goes:
We went through our code recently and modified most try/catch blocks to try+/catch, using additional functionality provided by slingshot. So far so good. Problem is, we often had a (catch Exception e...) clause at the end, that was supposed to catch pretty much everything that could happen in that block and perform cleanups.
Now, things were fine as long as exceptions were thrown by java code. But then it turned out that clj-http throws its unexpected-status exceptions (like "403 forbidden", see wrap-exceptions in client.clj in clj-http) using throw+. And what gets passed to throw+ is a response object (a map) and a string.
The result was that our code worked fine as long as the block around clj-http used (try/catch), but completely missed the exception when try was changed to try+, because slingshot would "unpack" the object that was thrown, find a map, and try to match that. And (catch Exception e...) would not match a map.
To demonstrate the problem:
(try (http-request {:url "http://fablo-data-production-eu-west-1.s3.amazonaws.com/no-permission" :method :get}) (catch Exception e (prn "got it" (.toString e))))
"got it" "slingshot.ExceptionInfo: clj-http: status 403"
-- this is fine and what I would expect.
(try+ (http-request {:url "http://fablo-data-production-eu-west-1.s3.amazonaws.com/no-permission" :method :get}) (catch Exception e (prn "got it" (.toString e))))
this does not get caught and SLIME catches the exception: clj-http: status 403 [Thrown class slingshot.ExceptionInfo], which I think is a problem.
There are actually several problems here.
- I'm not at all sure if library code (like clj-http) should use throw+ outside a try+ block.
- I would expect (catch Exception e) to catch every exception. If it does not, it means that try+ is not a replacement for try and one should be very, very careful using it.
- I need to have a way to catch everything, and I'm not sure if (catch (constantly true)) is the best idea.
As a temporary workaround I'll hunt down my try+ blocks and introduce (catch (constantly true)) or (catch Object), but I wanted to bring it up and see what you think.
I'm not actually sure if this is an issue or a question, but it certainly was unexpected and caused problems in my existing software, so here goes:
We went through our code recently and modified most try/catch blocks to try+/catch, using additional functionality provided by slingshot. So far so good. Problem is, we often had a (catch Exception e...) clause at the end, that was supposed to catch pretty much everything that could happen in that block and perform cleanups.
Now, things were fine as long as exceptions were thrown by java code. But then it turned out that clj-http throws its unexpected-status exceptions (like "403 forbidden", see wrap-exceptions in client.clj in clj-http) using throw+. And what gets passed to throw+ is a response object (a map) and a string.
The result was that our code worked fine as long as the block around clj-http used (try/catch), but completely missed the exception when try was changed to try+, because slingshot would "unpack" the object that was thrown, find a map, and try to match that. And (catch Exception e...) would not match a map.
To demonstrate the problem:
(try (http-request {:url "http://fablo-data-production-eu-west-1.s3.amazonaws.com/no-permission" :method :get}) (catch Exception e (prn "got it" (.toString e))))
"got it" "slingshot.ExceptionInfo: clj-http: status 403"
-- this is fine and what I would expect.
(try+ (http-request {:url "http://fablo-data-production-eu-west-1.s3.amazonaws.com/no-permission" :method :get}) (catch Exception e (prn "got it" (.toString e))))
this does not get caught and SLIME catches the exception: clj-http: status 403 [Thrown class slingshot.ExceptionInfo], which I think is a problem.
There are actually several problems here.
As a temporary workaround I'll hunt down my try+ blocks and introduce (catch (constantly true)) or (catch Object), but I wanted to bring it up and see what you think.