From 565c633435cb97755327f5a89bf6982e04f400e8 Mon Sep 17 00:00:00 2001 From: Harald Nordgren Date: Mon, 2 Dec 2024 18:56:31 +0100 Subject: [PATCH] Return full errors --- graphql/client.go | 13 +++++++- graphql/client_test.go | 73 +++++++++++++++++++++++++++++++----------- graphql/errors.go | 2 +- 3 files changed, 68 insertions(+), 20 deletions(-) diff --git a/graphql/client.go b/graphql/client.go index 82787596..04777721 100644 --- a/graphql/client.go +++ b/graphql/client.go @@ -265,9 +265,20 @@ func (c *client) MakeRequest(ctx context.Context, req *Request, resp *Response) if err != nil { respBody = []byte(fmt.Sprintf("", err)) } + + var gqlResp Response + if err := json.Unmarshal(respBody, &gqlResp); err != nil { + return &HTTPError{ + StatusCode: httpResp.StatusCode, + Body: Response{ + Errors: gqlerror.List{&gqlerror.Error{Message: string(respBody)}}, + }, + } + } + return &HTTPError{ StatusCode: httpResp.StatusCode, - Body: string(respBody), + Body: gqlResp, } } diff --git a/graphql/client_test.go b/graphql/client_test.go index 5eef22c3..4beff530 100644 --- a/graphql/client_test.go +++ b/graphql/client_test.go @@ -9,36 +9,74 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/vektah/gqlparser/v2/gqlerror" ) func TestMakeRequest_HTTPError(t *testing.T) { testCases := []struct { name string - serverResponseBody string - expectedErrorBody string serverResponseCode int - expectedStatusCode int + serverResponseBody any + expectedError *HTTPError }{ { - name: "400 Bad Request", - serverResponseBody: "Bad Request", - expectedErrorBody: "Bad Request", + name: "plain_text_error", serverResponseCode: http.StatusBadRequest, - expectedStatusCode: http.StatusBadRequest, + serverResponseBody: "Bad Request", + expectedError: &HTTPError{ + Body: Response{ + Errors: gqlerror.List{ + &gqlerror.Error{ + Message: "\"Bad Request\"\n", + }, + }, + }, + StatusCode: http.StatusBadRequest, + }, }, { - name: "429 Too Many Requests", - serverResponseBody: "Rate limit exceeded", - expectedErrorBody: "Rate limit exceeded", + name: "json_error_with_extensions", serverResponseCode: http.StatusTooManyRequests, - expectedStatusCode: http.StatusTooManyRequests, + serverResponseBody: Response{ + Errors: gqlerror.List{ + &gqlerror.Error{ + Message: "Rate limit exceeded", + Extensions: map[string]interface{}{ + "code": "RATE_LIMIT_EXCEEDED", + }, + }, + }, + }, + expectedError: &HTTPError{ + Body: Response{ + Errors: gqlerror.List{ + &gqlerror.Error{ + Message: "Rate limit exceeded", + Extensions: map[string]interface{}{ + "code": "RATE_LIMIT_EXCEEDED", + }, + }, + }, + }, + StatusCode: http.StatusTooManyRequests, + }, }, { - name: "500 Internal Server Error", - serverResponseBody: "Internal Server Error", - expectedErrorBody: "Internal Server Error", + name: "json_error_without_extensions", serverResponseCode: http.StatusInternalServerError, - expectedStatusCode: http.StatusInternalServerError, + serverResponseBody: Response{ + Errors: gqlerror.List{ + &gqlerror.Error{Message: "Internal Server Error"}, + }, + }, + expectedError: &HTTPError{ + Body: Response{ + Errors: gqlerror.List{ + &gqlerror.Error{Message: "Internal Server Error"}, + }, + }, + StatusCode: http.StatusInternalServerError, + }, }, } @@ -46,7 +84,7 @@ func TestMakeRequest_HTTPError(t *testing.T) { t.Run(tc.name, func(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(tc.serverResponseCode) - _, err := w.Write([]byte(tc.serverResponseBody)) + err := json.NewEncoder(w).Encode(tc.serverResponseBody) if err != nil { t.Fatalf("Failed to write response: %v", err) } @@ -64,8 +102,7 @@ func TestMakeRequest_HTTPError(t *testing.T) { assert.Error(t, err) var httpErr *HTTPError assert.True(t, errors.As(err, &httpErr), "Error should be of type *HTTPError") - assert.Equal(t, tc.expectedStatusCode, httpErr.StatusCode) - assert.Equal(t, tc.expectedErrorBody, httpErr.Body) + assert.Equal(t, tc.expectedError, httpErr) }) } } diff --git a/graphql/errors.go b/graphql/errors.go index d346cd1e..6bd38040 100644 --- a/graphql/errors.go +++ b/graphql/errors.go @@ -4,7 +4,7 @@ import "fmt" // HTTPError represents an HTTP error with status code and response body. type HTTPError struct { - Body string + Body Response StatusCode int }