-
Notifications
You must be signed in to change notification settings - Fork 4
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
Non-success status codes should not always result in a thrown exception #30
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,13 +29,35 @@ | |
(or (get-in response [:headers :content-type]) | ||
(get-in response [:headers "Content-Type"]))) | ||
|
||
(defn request [client req-map] | ||
(let [response @(httpkit/request (prepare client req-map))] | ||
(if (success-codes (:status response)) | ||
(update response :body (partial parse-body (content-type response))) | ||
(defn request | ||
"Sends a synchronous request to GitHub, largely as a wrapper around HTTP Kit. | ||
|
||
In addition to normal HTTP Kit keys in the request map, two additional keys are added. | ||
|
||
:path - used to create the :url key for HTTP kit; this is the path relative to https://api.github.com. | ||
|
||
:throw? - if true (the default), then non-success status codes result in a thrown exception. | ||
If set to false, then the response is returned, regardless and the caller can decide what to do | ||
with failure statuses." | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💯 for adding better docs. Maybe specific what Also add that in case of success the response body is conditionally parsed into json as returned as a clojure data structure. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Adding docs is what I do ™️. |
||
[client req-map] | ||
(let [{:keys [throw?] | ||
:or {throw? true}} req-map | ||
{:keys [error status body opts] :as response} @(httpkit/request (prepare client req-map))] | ||
(cond | ||
error | ||
(throw (ex-info "Failure sending request to GitHub" | ||
{:opts opts} | ||
error)) | ||
|
||
(and throw? | ||
(not (success-codes status))) | ||
(throw (ex-info "Request to GitHub failed" | ||
{:response (select-keys response [:status :body])} | ||
(:error response)))))) | ||
{:response (select-keys response [:status :body]) | ||
:opts opts} | ||
error)) | ||
|
||
:else | ||
(assoc response :body (parse-body (content-type response) body))))) | ||
|
||
(defn new-client [{:keys [app-id private-key token org] :as opts}] | ||
(cond | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,11 +31,18 @@ | |
"Content-Type" "application/json"}} | ||
{:status 200}] | ||
(is (match? {:status 200} (sut/request client {}))))) | ||
(testing "it throws an exception when status code is not succesful" | ||
(testing "it throws an exception when status code is not successful" | ||
(with-fake-http [{} {:status 400}] | ||
(is (thrown-with-msg? clojure.lang.ExceptionInfo #"(?i)Request to GitHub failed" | ||
(sut/request client {}))))) | ||
;; in case of lower level errors, e.g. DNS lookup failue there will not be a status code | ||
(testing "it does not throw with a failure status if so enabled" | ||
(with-fake-http [{:headers {"Authorization" "Bearer token" | ||
"Content-Type" "application/json"}} | ||
{:status 404}] | ||
(is (match? | ||
{:status 404} | ||
(sut/request client {:throw? false}))))) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You should also verify that the headers and body are not mangled. |
||
;; in case of lower level errors, e.g. DNS lookup failure there will not be a status code | ||
(testing "it throws an exception when there is no status code" | ||
(with-fake-http [{} {:status nil}] | ||
(is (thrown-with-msg? clojure.lang.ExceptionInfo #"(?i)Request to GitHub failed" | ||
|
@@ -44,7 +51,7 @@ | |
(let [cause (Exception. "Exception for testing purpose")] | ||
(with-fake-http [{} {:error cause :status nil}] | ||
(let [e (try (sut/request client {}) (catch Exception e e))] | ||
(is (re-matches #"(?i)Request to GitHub failed" (.getMessage e))) | ||
(is (re-matches #"(?i)Failure sending request to GitHub" (.getMessage e))) | ||
(is (= cause (.getCause e))))))) | ||
(testing "url path contains special character `|`" | ||
(with-fake-http [{:url "https://api.github.com/test%7Ctest"} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are the version bumps essential to this PR? Otherwise separate them out at least to a separate commit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When the cost of getting a commit merged is too high, you tend to put a lot into one PR. These changes are not essential, but I tend to update dependencies as hygiene, when possible.