Skip to content

Commit

Permalink
Merge a12f4ef into 39f027c
Browse files Browse the repository at this point in the history
  • Loading branch information
JulienTant committed Oct 11, 2019
2 parents 39f027c + a12f4ef commit 7fccfe4
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 2 deletions.
14 changes: 13 additions & 1 deletion client.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,18 @@ func NewClient(
return &Client{Client: kithttp.NewClient(method, tgt, enc, makeDecodeResponseFunc(dec), options...)}
}

// NewClientWithError creates a kitty client that doesn't deal with HTTP errors.
// and let you do it while you decode.
func NewClientWithError(
method string,
tgt *url.URL,
enc kithttp.EncodeRequestFunc,
dec kithttp.DecodeResponseFunc,
options ...kithttp.ClientOption,
) *Client {
return &Client{Client: kithttp.NewClient(method, tgt, enc, dec, options...)}
}

// makeDecodeResponseFunc maps HTTP errors to Go errors.
func makeDecodeResponseFunc(fn kithttp.DecodeResponseFunc) kithttp.DecodeResponseFunc {
return func(ctx context.Context, resp *http.Response) (interface{}, error) {
Expand All @@ -36,4 +48,4 @@ func makeDecodeResponseFunc(fn kithttp.DecodeResponseFunc) kithttp.DecodeRespons
}
return fn(ctx, resp)
}
}
}
57 changes: 56 additions & 1 deletion client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,58 @@ func TestClient(t *testing.T) {
}
}

func TestClientWithError(t *testing.T) {
h := testHandler{}
ts := httptest.NewServer(&h)
defer ts.Close()

client := ts.Client()
u, _ := url.Parse(ts.URL)
e := NewClientWithError("GET", u, kithttp.EncodeJSONRequest, decodeTestResponse, kithttp.SetClient(client)).Endpoint()

h.statuses = []int{http.StatusServiceUnavailable}
resp, err := e(context.TODO(), nil)
if err != nil {
t.Error("When calling a failed server, the client with error should NOT return an error")
}
v, ok := resp.(testStruct)
if ok == false {
t.Errorf("The returned response must be decoded, got %#v", resp)
}
if v.err == nil {
t.Error("The response has not been correctly decoded")
}

if !IsRetryable(v.err) {
t.Error("The returned error for http.StatusServiceUnavailable should be retryable")
}

h.statuses = []int{http.StatusBadRequest}
resp, err = e(context.TODO(), nil)
if err != nil {
t.Error("When calling a failed server, the client with error should NOT return an error")
}
v, ok = resp.(testStruct)
if ok == false {
t.Errorf("The returned response must be decoded, got %#v", resp)
}
if v.err == nil {
t.Error("The response has not been correctly decoded")
}
if IsRetryable(v.err) {
t.Error("The returned error for http.StatusBadRequest should not be retryable")
}


h.statuses = []int{}
res, err := e(context.TODO(), nil)
if err != nil {
t.Errorf("When calling a working server, the client should not return an error, got %s", err)
} else if !reflect.DeepEqual(res, testData) {
t.Errorf("The endpoint returned invalid data : %+v", res)
}
}

var testData = testStruct{Foo: "bar"}

type testHandler struct {
Expand All @@ -57,14 +109,17 @@ func (h *testHandler) ServeHTTP(w http.ResponseWriter, _ *http.Request) {
h.statuses = h.statuses[1:]
} else {
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(testData)
}
json.NewEncoder(w).Encode(testData)
}

func decodeTestResponse(ctx context.Context, resp *http.Response) (interface{}, error) {
response := testStruct{}
if err := json.NewDecoder(resp.Body).Decode(&response); err != nil {
return nil, err
}

response.err = HTTPError(resp)

return response, nil
}
1 change: 1 addition & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80n
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw=
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sony/gobreaker v0.4.1 h1:oMnRNZXX5j85zso6xCPRNPtmAycat+WcoKbklScLDgQ=
Expand Down
2 changes: 2 additions & 0 deletions server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ func TestServer(t *testing.T) {
type testStruct struct {
Foo string `json:"foo"`
Status int `json:"status"`

err error
}

func testEP(_ context.Context, req interface{}) (interface{}, error) {
Expand Down

0 comments on commit 7fccfe4

Please sign in to comment.