diff --git a/graphql/client.go b/graphql/client.go index 8278759..f1ef3e7 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 5eef22c..eea16ee 100644 --- a/graphql/client_test.go +++ b/graphql/client_test.go @@ -9,36 +9,57 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/vektah/gqlparser/v2/gqlerror" ) func TestMakeRequest_HTTPError(t *testing.T) { testCases := []struct { + expectedError *HTTPError + serverResponseBody any name string - serverResponseBody string - expectedErrorBody string serverResponseCode int - expectedStatusCode int }{ { - 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, - }, - { - name: "500 Internal Server Error", - serverResponseBody: "Internal Server Error", - expectedErrorBody: "Internal Server Error", - serverResponseCode: http.StatusInternalServerError, - expectedStatusCode: http.StatusInternalServerError, + 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, + }, }, } @@ -46,7 +67,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 +85,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 d346cd1..6bd3804 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 }