Skip to content

Commit 9f62aff

Browse files
author
Ulf Gitschthaler
committed
4xx http status code should not trigger a bad_request event
1 parent 73cf95a commit 9f62aff

File tree

2 files changed

+32
-61
lines changed

2 files changed

+32
-61
lines changed

src/clj_http_hystrix/core.clj

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55
[slingshot.slingshot :refer [get-thrown-object]]
66
[slingshot.support :refer [wrap stack-trace]])
77
(:import [com.netflix.hystrix HystrixCommand
8-
HystrixThreadPoolProperties
9-
HystrixCommandProperties
10-
HystrixCommand$Setter
11-
HystrixCommandGroupKey$Factory
12-
HystrixCommandKey$Factory]
8+
HystrixThreadPoolProperties
9+
HystrixCommandProperties
10+
HystrixCommand$Setter
11+
HystrixCommandGroupKey$Factory
12+
HystrixCommandKey$Factory]
1313
[com.netflix.hystrix.exception HystrixBadRequestException]
1414
[org.slf4j MDC]))
1515

@@ -43,8 +43,7 @@
4343
:hystrix/timeout-ms 1000
4444
:hystrix/breaker-request-volume 20
4545
:hystrix/breaker-error-percent 50
46-
:hystrix/breaker-sleep-window-ms 5000
47-
:hystrix/bad-request-pred client-error?})
46+
:hystrix/breaker-sleep-window-ms 5000})
4847

4948
(def ^:private hystrix-keys
5049
(keys hystrix-base-configuration))
@@ -109,20 +108,10 @@
109108
(fn [f req]
110109
(if (not-empty (select-keys req hystrix-keys))
111110
(let [req (merge defaults req)
112-
bad-request-pred (:hystrix/bad-request-pred req)
113111
fallback (:hystrix/fallback-fn req)
114-
wrap-bad-request (fn [resp]
115-
(if (bad-request-pred req resp)
116-
(throw
117-
(HystrixBadRequestException.
118-
"Ignored bad request"
119-
(wrap {:object resp
120-
:message "Bad request pred"
121-
:stack-trace (stack-trace)})))
122-
resp))
123112
wrap-exception-response (fn [resp]
124113
((http/wrap-exceptions (constantly resp))
125-
(assoc req :throw-exceptions true)))
114+
(assoc req :throw-exceptions (not (client-error? req resp)))))
126115
configurator (configurator req)
127116
logging-context (or (MDC/getCopyOfContextMap) {})
128117
command (proxy [HystrixCommand] [configurator]
@@ -137,7 +126,6 @@
137126
(-> req
138127
(assoc :throw-exceptions false)
139128
f
140-
wrap-bad-request
141129
wrap-exception-response)))]
142130
(handle-exception #(.execute command) req))
143131
(f req)))))

test/clj_http_hystrix/core_test.clj

Lines changed: 25 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@
113113
:throw-exceptions false})]
114114
(:status response) => 503)))
115115

116-
(fact "errors will not cause circuit to break if bad-request-pred is true, with :throw-exceptions false"
116+
(fact "errors will not cause circuit to break if client-error? is true, with :throw-exceptions false"
117117
(rest-driven
118118
[{:method :GET
119119
:url "/"}
@@ -125,13 +125,12 @@
125125
(let [command-key (keyword (str (UUID/randomUUID)))]
126126
(dotimes [_ 30]
127127
(http/get url {:throw-exceptions false
128-
:hystrix/command-key command-key
129-
:hystrix/bad-request-pred client-error?}) => (contains {:status 400}))
128+
:hystrix/command-key command-key}) => (contains {:status 400}))
130129
(Thread/sleep 600) ;sleep to wait for Hystrix health snapshot
131130
(http/get url {:throw-exceptions false
132131
:hystrix/command-key command-key}) => (contains {:status 200}))))
133132

134-
(fact "errors will not cause circuit to break if bad-request-pred is true, with :throw-exceptions true"
133+
(fact "errors will not cause circuit to break if client-error? is true, with :throw-exceptions true"
135134
(rest-driven
136135
[{:method :GET
137136
:url "/"}
@@ -143,27 +142,11 @@
143142
(let [command-key (keyword (str (UUID/randomUUID)))]
144143
(dotimes [_ 30]
145144
(http/get url {:throw-exceptions true
146-
:hystrix/command-key command-key
147-
:hystrix/bad-request-pred client-error?}) => (throws ExceptionInfo))
145+
:hystrix/command-key command-key}) => (throws ExceptionInfo))
148146
(Thread/sleep 600) ;sleep to wait for Hystrix health snapshot
149147
(http/get url {:throw-exceptions false
150148
:hystrix/command-key command-key}) => (contains {:status 200}))))
151149

152-
(fact "errors will cause circuit to break if bad-request-pred is false"
153-
(rest-driven
154-
[{:method :GET
155-
:url "/"}
156-
{:status 400
157-
:times 30}]
158-
(let [command-key (keyword (str (UUID/randomUUID)))]
159-
(dotimes [_ 30]
160-
(http/get url {:throw-exceptions false
161-
:hystrix/command-key command-key
162-
:hystrix/bad-request-pred (constantly false)}) => (contains {:status 400}))
163-
(Thread/sleep 600) ;sleep to wait for Hystrix health snapshot
164-
(http/get url {:throw-exceptions false
165-
:hystrix/command-key command-key}) => (contains {:status 503}))))
166-
167150
(fact "status-codes predicate matches only given status codes"
168151
(let [predicate (status-codes 100 200 300)]
169152
(predicate {} {:status 100}) => true
@@ -197,17 +180,17 @@
197180

198181
(fact "add-hook with user-defaults will override base configuration, but not call configuration"
199182
(rest-driven
200-
[{:method :GET
201-
:url "/"}
202-
{:status 500
203-
:times 3}]
204-
(make-hystrix-call {})
205-
=> (throws clojure.lang.ExceptionInfo "clj-http: status 500")
183+
[{:method :GET
184+
:url "/"}
185+
{:status 500
186+
:times 3}]
187+
(make-hystrix-call {})
188+
=> (throws clojure.lang.ExceptionInfo "clj-http: status 500")
206189
;set custom default for fallback-fn
207-
(remove-hook)
208-
(add-hook {:hystrix/fallback-fn (constantly "bar")})
209-
(make-hystrix-call {}) => "bar"
210-
(make-hystrix-call {:hystrix/fallback-fn (constantly "baz")}) => "baz")
190+
(remove-hook)
191+
(add-hook {:hystrix/fallback-fn (constantly "bar")})
192+
(make-hystrix-call {}) => "bar"
193+
(make-hystrix-call {:hystrix/fallback-fn (constantly "baz")}) => "baz")
211194
(remove-hook)
212195
(add-hook))
213196

@@ -216,19 +199,19 @@
216199
;verify hystrix is enabled by exceeding the default timeout (1000 ms)
217200
(http/with-additional-middleware [wrap-hystrix]
218201
(rest-driven
219-
[{:method :GET
220-
:url "/"}
221-
{:status 200
222-
:after 1500}]
223-
(make-hystrix-call {})
224-
=> (throws clojure.lang.ExceptionInfo "clj-http: status 503")))
202+
[{:method :GET
203+
:url "/"}
204+
{:status 200
205+
:after 1500}]
206+
(make-hystrix-call {})
207+
=> (throws clojure.lang.ExceptionInfo "clj-http: status 503")))
225208

226209
;verify custom defaults are supported
227210
(http/with-additional-middleware
228211
[(partial wrap-hystrix {:hystrix/fallback-fn (constantly {:status 404})})]
229212
(rest-driven
230-
[{:method :GET
231-
:url "/"}
232-
{:status 500}]
233-
(make-hystrix-call {})
234-
=> (throws clojure.lang.ExceptionInfo "clj-http: status 404"))))
213+
[{:method :GET
214+
:url "/"}
215+
{:status 500}]
216+
(make-hystrix-call {})
217+
=> (throws clojure.lang.ExceptionInfo "clj-http: status 404"))))

0 commit comments

Comments
 (0)