From 44c05fece4fdb20ee8cb602d046babed672fad30 Mon Sep 17 00:00:00 2001 From: Joakim Olsson Date: Tue, 1 Jul 2025 08:27:42 +0200 Subject: [PATCH] fix(client): handle error responses with detailed messages Adds error handling for non-OK HTTP status codes in the client. Implements custom error messages by reading the response body when the status code indicates an error, ensuring better debugging and clarity during failures. Enhances unit tests to cover unauthorized access and incorrect body length scenarios, validating the error handling mechanism. --- gitlab/client.go | 6 ++++++ gitlab/client_test.go | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/gitlab/client.go b/gitlab/client.go index 3c9c52d..ac033bd 100644 --- a/gitlab/client.go +++ b/gitlab/client.go @@ -69,6 +69,12 @@ func (r *RestClient) projectApiCall(method, project string, api string, body io. if resp.StatusCode == http.StatusOK && response != nil { decoder := json.NewDecoder(resp.Body) err = decoder.Decode(response) + } else if resp.StatusCode != http.StatusOK { + buff, err2 := io.ReadAll(resp.Body) + if err2 != nil { + return fmt.Errorf("error reading body: %w", err2) + } + return fmt.Errorf("status %d: %s", resp.StatusCode, string(buff)) } return err } diff --git a/gitlab/client_test.go b/gitlab/client_test.go index dcb2f5f..bca1ac0 100644 --- a/gitlab/client_test.go +++ b/gitlab/client_test.go @@ -80,6 +80,39 @@ func TestRestClient_GetTags(t *testing.T) { return assert.EqualError(t, err, "invalid character 'a' looking for beginning of value") }, }, + { + name: "unauthorized", + args: args{ + project: "unboundsoftware/dummy", + }, + handler: func(t *testing.T) http.HandlerFunc { + return func(writer http.ResponseWriter, request *http.Request) { + writer.WriteHeader(http.StatusUnauthorized) + _, _ = writer.Write([]byte("token expired")) + } + }, + want: nil, + wantErr: func(t assert.TestingT, err error, i ...interface{}) bool { + return assert.EqualError(t, err, "status 401: token expired") + }, + }, + { + name: "error body length incorrect", + args: args{ + project: "unboundsoftware/dummy", + }, + handler: func(t *testing.T) http.HandlerFunc { + return func(writer http.ResponseWriter, request *http.Request) { + writer.Header().Set("Content-Length", "230") + writer.WriteHeader(http.StatusUnauthorized) + _, _ = writer.Write([]byte("token expired")) + } + }, + want: nil, + wantErr: func(t assert.TestingT, err error, i ...interface{}) bool { + return assert.EqualError(t, err, "error reading body: unexpected EOF") + }, + }, { name: "success", args: args{