-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Can't retrieve response body with :as :stream, :throw-exception? true
#37
Comments
Hey @aeriksson thanks for this! The idea I was having is this is akin to calling a function which could possibly throw, so either the return value or the exception is the outcome of the call. But yes this is an interesting case and I can think of maybe wrapping the return as part of the exception somehow. Also could you describe me a scenario where/how you could use the stream(or any other value) when an exception is thorwn? This would help me think of a better solution. And yes, any and every help is much welcome! 😄 |
Sure! I'm copying files to/from Docker via I want to:
The problem here is that I'm currently only able to see the response status code in the thrown exception, whereas I'd like to be able to see the response body as well (so I can log and handle the error appropriately). One way to solve this that would make me happy at least is if you would just slurp the response body before throwing the exception (I'll have to parse the response body either way when there's a failure, so it's fine if you slurp it — AFAICT Docker errors are normally pretty small anyway, so the overhead should be minimal). |
@xsc for this issue would slurping and assoc-ing the body from the inputstream here https://github.com/into-docker/unixsocket-http/blob/master/src/unixsocket_http/core.clj#L61 would be a good solution? I can raise a PR if you think so? |
@lispyclouds @aeriksson Wouldn't the following address the use case? (let [{:keys [status body]}
(docker/invoke client {:op :ContainerArchive
:params {:id "foo", :path "/not-a-path"}
:as :stream
:throw-exception? false})]
(if (>= status 400)
(with-open [in body]
(let [error-data (slurp in)]
...)) ;; error!
...)) ;; success! At least that's how I imagine it from |
This works too! I guess @aeriksson 's control flow was that an exception was raised? |
@xsc yeah that works too — I didn't realize I could check the status without consuming the body. Regardless, I think something like @lispyclouds's suggestion would be good — it's a bit counterintuitive that the body can't be accessed when an exception is thrown and |
@aeriksson I think there is a high risk that people would forget to close the stream if it was kept open when an exception is thrown. I'd argue that it's not good practice to leave exception cleanup to the user. For the alternative, I also think it's not good practice to consume the stream into memory. I know I'm constructing a case here, but what if the response has status 404 and 1TB of debug data in the body? 💥 This is my view for For Docker, the endpoints and amounts of data are known, so there is no actual risk. Additionally, I'm not sure my snippet of code up there actually works since So, potential options:
|
@xsc very fair points and I too would think the |
Edit: While testing |
Implemented in |
So if I invoke a command with both
:as :stream
and:throw-exception? true
, there seems to be no way to read the response body. For instance, doing:just gives me something like
while
throws
java.io.IOException: closed
.There should be some way to read the response body when things fail.
The text was updated successfully, but these errors were encountered: