From 1133adc45928344a9b0886d4073fd91d8db52a1f Mon Sep 17 00:00:00 2001 From: eiixy <990656271@qq.com> Date: Fri, 20 Sep 2024 18:27:51 +0800 Subject: [PATCH 1/6] update client error return --- client.go | 9 +++++++++ error.go | 6 ++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/client.go b/client.go index 9f547e7cb..4555645e4 100644 --- a/client.go +++ b/client.go @@ -285,10 +285,18 @@ func (c *Client) baseURLWithAzureDeployment(baseURL, suffix, model string) (newB } func (c *Client) handleErrorResp(resp *http.Response) error { + if !strings.HasPrefix(resp.Header.Get("Content-Type"), "application/json") { + body, err := io.ReadAll(resp.Body) + if err != nil { + return err + } + return fmt.Errorf("error, status code: %d, status: %s, body: %s", resp.StatusCode, resp.Status, body) + } var errRes ErrorResponse err := json.NewDecoder(resp.Body).Decode(&errRes) if err != nil || errRes.Error == nil { reqErr := &RequestError{ + HTTPStatus: resp.Status, HTTPStatusCode: resp.StatusCode, Err: err, } @@ -298,6 +306,7 @@ func (c *Client) handleErrorResp(resp *http.Response) error { return reqErr } + errRes.Error.HTTPStatus = resp.Status errRes.Error.HTTPStatusCode = resp.StatusCode return errRes.Error } diff --git a/error.go b/error.go index 37959a272..1f6a8971d 100644 --- a/error.go +++ b/error.go @@ -13,6 +13,7 @@ type APIError struct { Message string `json:"message"` Param *string `json:"param,omitempty"` Type string `json:"type"` + HTTPStatus string `json:"-"` HTTPStatusCode int `json:"-"` InnerError *InnerError `json:"innererror,omitempty"` } @@ -25,6 +26,7 @@ type InnerError struct { // RequestError provides information about generic request errors. type RequestError struct { + HTTPStatus string HTTPStatusCode int Err error } @@ -35,7 +37,7 @@ type ErrorResponse struct { func (e *APIError) Error() string { if e.HTTPStatusCode > 0 { - return fmt.Sprintf("error, status code: %d, message: %s", e.HTTPStatusCode, e.Message) + return fmt.Sprintf("error, status code: %d, status: %s, message: %s", e.HTTPStatusCode, e.HTTPStatus, e.Message) } return e.Message @@ -101,7 +103,7 @@ func (e *APIError) UnmarshalJSON(data []byte) (err error) { } func (e *RequestError) Error() string { - return fmt.Sprintf("error, status code: %d, message: %s", e.HTTPStatusCode, e.Err) + return fmt.Sprintf("error, status code: %d, status: %s, message: %s", e.HTTPStatusCode, e.HTTPStatus, e.Err) } func (e *RequestError) Unwrap() error { From 0e2b5b7a7f24206f2f5be7ec0b68801e024fc01e Mon Sep 17 00:00:00 2001 From: eiixy <990656271@qq.com> Date: Fri, 20 Sep 2024 19:08:05 +0800 Subject: [PATCH 2/6] update client_test.go --- client_test.go | 74 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 52 insertions(+), 22 deletions(-) diff --git a/client_test.go b/client_test.go index 7119d8a7e..daead0e5e 100644 --- a/client_test.go +++ b/client_test.go @@ -134,14 +134,18 @@ func TestHandleErrorResp(t *testing.T) { client := NewClient(mockToken) testCases := []struct { - name string - httpCode int - body io.Reader - expected string + name string + httpCode int + httpStatus string + contentType string + body io.Reader + expected string }{ { - name: "401 Invalid Authentication", - httpCode: http.StatusUnauthorized, + name: "401 Invalid Authentication", + httpCode: http.StatusUnauthorized, + httpStatus: "", + contentType: "application/json", body: bytes.NewReader([]byte( `{ "error":{ @@ -152,11 +156,12 @@ func TestHandleErrorResp(t *testing.T) { } }`, )), - expected: "error, status code: 401, message: You didn't provide an API key. ....", + expected: "error, status code: 401, status: , message: You didn't provide an API key. ....", }, { - name: "401 Azure Access Denied", - httpCode: http.StatusUnauthorized, + name: "401 Azure Access Denied", + httpCode: http.StatusUnauthorized, + contentType: "application/json", body: bytes.NewReader([]byte( `{ "error":{ @@ -165,11 +170,12 @@ func TestHandleErrorResp(t *testing.T) { } }`, )), - expected: "error, status code: 401, message: Access denied due to Virtual Network/Firewall rules.", + expected: "error, status code: 401, status: , message: Access denied due to Virtual Network/Firewall rules.", }, { - name: "503 Model Overloaded", - httpCode: http.StatusServiceUnavailable, + name: "503 Model Overloaded", + httpCode: http.StatusServiceUnavailable, + contentType: "application/json", body: bytes.NewReader([]byte(` { "error":{ @@ -179,22 +185,46 @@ func TestHandleErrorResp(t *testing.T) { "code":null } }`)), - expected: "error, status code: 503, message: That model...", + expected: "error, status code: 503, status: , message: That model...", }, { - name: "503 no message (Unknown response)", - httpCode: http.StatusServiceUnavailable, + name: "503 no message (Unknown response)", + httpCode: http.StatusServiceUnavailable, + contentType: "application/json", body: bytes.NewReader([]byte(` { "error":{} }`)), - expected: "error, status code: 503, message: ", + expected: "error, status code: 503, status: , message: ", + }, + { + name: "413 Request Entity Too Large", + httpCode: http.StatusRequestEntityTooLarge, + contentType: "text/html", + body: bytes.NewReader([]byte(` +413 Request Entity Too Large + +

413 Request Entity Too Large

+
nginx
+ +`)), + expected: `error, status code: 413, status: , body: +413 Request Entity Too Large + +

413 Request Entity Too Large

+
nginx
+ +`, }, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - testCase := &http.Response{} + testCase := &http.Response{ + Header: map[string][]string{ + "Content-Type": {tc.contentType}, + }, + } testCase.StatusCode = tc.httpCode testCase.Body = io.NopCloser(tc.body) err := client.handleErrorResp(testCase) @@ -204,11 +234,11 @@ func TestHandleErrorResp(t *testing.T) { t.Fail() } - e := &APIError{} - if !errors.As(err, &e) { - t.Errorf("(%s) Expected error to be of type APIError", tc.name) - t.Fail() - } + //e := &APIError{} + //if !errors.As(err, &e) { + // t.Errorf("(%s) Expected error to be of type APIError", tc.name) + // t.Fail() + //} }) } } From 55eeaa4ca3c38a518c87bf1bc70ac00728fd4c07 Mon Sep 17 00:00:00 2001 From: eiixy <990656271@qq.com> Date: Fri, 20 Sep 2024 19:10:28 +0800 Subject: [PATCH 3/6] update client_test.go --- client_test.go | 7 ------- 1 file changed, 7 deletions(-) diff --git a/client_test.go b/client_test.go index daead0e5e..2cad8fabc 100644 --- a/client_test.go +++ b/client_test.go @@ -144,7 +144,6 @@ func TestHandleErrorResp(t *testing.T) { { name: "401 Invalid Authentication", httpCode: http.StatusUnauthorized, - httpStatus: "", contentType: "application/json", body: bytes.NewReader([]byte( `{ @@ -233,12 +232,6 @@ func TestHandleErrorResp(t *testing.T) { t.Errorf("Unexpected error: %v , expected: %s", err, tc.expected) t.Fail() } - - //e := &APIError{} - //if !errors.As(err, &e) { - // t.Errorf("(%s) Expected error to be of type APIError", tc.name) - // t.Fail() - //} }) } } From 17c79a024e8e4c1f4ab1db62d4f8681d8c0aa22a Mon Sep 17 00:00:00 2001 From: eiixy <990656271@qq.com> Date: Fri, 20 Sep 2024 19:20:02 +0800 Subject: [PATCH 4/6] update file_api_test.go --- files_api_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/files_api_test.go b/files_api_test.go index c92162a84..aa4fda458 100644 --- a/files_api_test.go +++ b/files_api_test.go @@ -152,6 +152,7 @@ func TestGetFileContentReturnError(t *testing.T) { client, server, teardown := setupOpenAITestServer() defer teardown() server.RegisterHandler("/v1/files/deadbeef/content", func(w http.ResponseWriter, _ *http.Request) { + w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusBadRequest) fmt.Fprint(w, wantErrorResp) }) From 9822ff05ae4472e82c81b1dfe967efd0a94c4f2f Mon Sep 17 00:00:00 2001 From: eiixy <990656271@qq.com> Date: Mon, 23 Sep 2024 18:28:10 +0800 Subject: [PATCH 5/6] update client_test.go --- client.go | 2 +- client_test.go | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/client.go b/client.go index 4555645e4..2897e0945 100644 --- a/client.go +++ b/client.go @@ -288,7 +288,7 @@ func (c *Client) handleErrorResp(resp *http.Response) error { if !strings.HasPrefix(resp.Header.Get("Content-Type"), "application/json") { body, err := io.ReadAll(resp.Body) if err != nil { - return err + return fmt.Errorf("error, reading response body: %s", err) } return fmt.Errorf("error, status code: %d, status: %s, body: %s", resp.StatusCode, resp.Status, body) } diff --git a/client_test.go b/client_test.go index 2cad8fabc..ea951835f 100644 --- a/client_test.go +++ b/client_test.go @@ -215,6 +215,13 @@ func TestHandleErrorResp(t *testing.T) { `, }, + { + name: "errorReader", + httpCode: http.StatusRequestEntityTooLarge, + contentType: "text/html", + body: &errorReader{err: errors.New("errorReader")}, + expected: "error, reading response body: errorReader", + }, } for _, tc := range testCases { From 159426819f108911fd583a5c8aeaf5497f6c8c96 Mon Sep 17 00:00:00 2001 From: eiixy <990656271@qq.com> Date: Mon, 23 Sep 2024 18:49:53 +0800 Subject: [PATCH 6/6] update client_test.go --- client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client.go b/client.go index 2897e0945..583244fe1 100644 --- a/client.go +++ b/client.go @@ -288,7 +288,7 @@ func (c *Client) handleErrorResp(resp *http.Response) error { if !strings.HasPrefix(resp.Header.Get("Content-Type"), "application/json") { body, err := io.ReadAll(resp.Body) if err != nil { - return fmt.Errorf("error, reading response body: %s", err) + return fmt.Errorf("error, reading response body: %w", err) } return fmt.Errorf("error, status code: %d, status: %s, body: %s", resp.StatusCode, resp.Status, body) }