From eb4cd51026ac458c924906ecaa453f8481f9a498 Mon Sep 17 00:00:00 2001 From: Quest Henkart Date: Mon, 1 May 2023 15:47:25 +0800 Subject: [PATCH 1/6] maintain underlying error structs to allow for type conversion and defensive error checking --- client.go | 9 +++++---- client_test.go | 2 +- error.go | 4 ++-- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/client.go b/client.go index 500b3d56e..6f1d57c5a 100644 --- a/client.go +++ b/client.go @@ -144,15 +144,16 @@ func (c *Client) handleErrorResp(resp *http.Response) error { var errRes ErrorResponse err := json.NewDecoder(resp.Body).Decode(&errRes) if err != nil || errRes.Error == nil { - reqErr := RequestError{ + reqErr := &RequestError{ HTTPStatusCode: resp.StatusCode, Err: err, } if errRes.Error != nil { - reqErr.Err = errRes.Error + reqErr.Err = fmt.Errorf(errRes.Error.Message) } - return fmt.Errorf("error, %w", &reqErr) + return reqErr } + errRes.Error.HTTPStatusCode = resp.StatusCode - return fmt.Errorf("error, status code: %d, message: %w", resp.StatusCode, errRes.Error) + return errRes.Error } diff --git a/client_test.go b/client_test.go index 7ef628487..38bf94827 100644 --- a/client_test.go +++ b/client_test.go @@ -106,7 +106,7 @@ func TestHandleErrorResp(t *testing.T) { } }`, )), - expected: "error, status code 401, message: Access denied due to Virtual Network/Firewall rules.", + expected: "error, status code: 401, message: Access denied due to Virtual Network/Firewall rules.", }, { name: "503 Model Overloaded", diff --git a/error.go b/error.go index 86b75f4bc..3942ac8c5 100644 --- a/error.go +++ b/error.go @@ -25,7 +25,7 @@ type ErrorResponse struct { } func (e *APIError) Error() string { - return e.Message + return fmt.Sprintf("error, status code: %d, message: %s", e.HTTPStatusCode, e.Message) } func (e *APIError) UnmarshalJSON(data []byte) (err error) { @@ -70,7 +70,7 @@ func (e *APIError) UnmarshalJSON(data []byte) (err error) { } func (e *RequestError) Error() string { - return fmt.Sprintf("status code %d, message: %s", e.HTTPStatusCode, e.Err) + return fmt.Sprintf("error, status code: %d, message: %s", e.HTTPStatusCode, e.Err) } func (e *RequestError) Unwrap() error { From 800d8fdf8aace6fbdccb83e4ab1b18f2121fa6dc Mon Sep 17 00:00:00 2001 From: Quest Henkart Date: Tue, 2 May 2023 07:59:14 +0800 Subject: [PATCH 2/6] allow Error.Is for Azure responses --- README.md | 8 +++----- client.go | 2 +- error.go | 6 +++++- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 7526ea333..159f76645 100644 --- a/README.md +++ b/README.md @@ -10,13 +10,13 @@ This library provides Go clients for [OpenAI API](https://platform.openai.com/). * DALLĀ·E 2 * Whisper -Installation: +### Installation: ``` go get github.com/sashabaranov/go-openai ``` -ChatGPT example usage: +### ChatGPT example usage: ```go package main @@ -52,9 +52,7 @@ func main() { ``` - - -Other examples: +### Other examples:
ChatGPT streaming completion diff --git a/client.go b/client.go index 6f1d57c5a..501473ea3 100644 --- a/client.go +++ b/client.go @@ -149,7 +149,7 @@ func (c *Client) handleErrorResp(resp *http.Response) error { Err: err, } if errRes.Error != nil { - reqErr.Err = fmt.Errorf(errRes.Error.Message) + reqErr.Err = errRes.Error } return reqErr } diff --git a/error.go b/error.go index 3942ac8c5..6354f43b5 100644 --- a/error.go +++ b/error.go @@ -25,7 +25,11 @@ type ErrorResponse struct { } func (e *APIError) Error() string { - return fmt.Sprintf("error, status code: %d, message: %s", e.HTTPStatusCode, e.Message) + if e.HTTPStatusCode > 0 { + return fmt.Sprintf("error, status code: %d, message: %s", e.HTTPStatusCode, e.Message) + } + + return e.Message } func (e *APIError) UnmarshalJSON(data []byte) (err error) { From 3f134284bda71cef0a9afe02697df200e47c124d Mon Sep 17 00:00:00 2001 From: Quest Henkart Date: Tue, 2 May 2023 08:12:08 +0800 Subject: [PATCH 3/6] update readme, add tests to ensure type conversion --- README.md | 24 ++++++++++++++++++++++++ client_test.go | 7 +++++++ 2 files changed, 31 insertions(+) diff --git a/README.md b/README.md index 159f76645..507ddbc27 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,30 @@ func main() { ``` + +### Error handling: + +Open-AI maintains clear documentation on how to [handle API errors](https://platform.openai.com/docs/guides/error-codes/api-errors) + +example: +``` +e := &APIError{} +if errors.As(err, &e) { + switch e.HTTPStatusCode { + case 401: + // invalid auth or key (do not retry) + case 429: + // rate limiting or engine overload (wait and retry) + case 500: + // openai server error (retry) + default: + // unhandled + } +} + +``` + + ### Other examples:
diff --git a/client_test.go b/client_test.go index 38bf94827..e30fa399b 100644 --- a/client_test.go +++ b/client_test.go @@ -2,6 +2,7 @@ package openai //nolint:testpackage // testing private field import ( "bytes" + "errors" "fmt" "io" "net/http" @@ -135,6 +136,12 @@ 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 d34941c4c863d0d84560b4ffa92a63f9a616c0fe Mon Sep 17 00:00:00 2001 From: Quest Henkart Date: Tue, 2 May 2023 08:13:48 +0800 Subject: [PATCH 4/6] fix whitespacing --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 507ddbc27..659e953b0 100644 --- a/README.md +++ b/README.md @@ -65,12 +65,12 @@ if errors.As(err, &e) { case 401: // invalid auth or key (do not retry) case 429: - // rate limiting or engine overload (wait and retry) - case 500: - // openai server error (retry) - default: - // unhandled - } + // rate limiting or engine overload (wait and retry) + case 500: + // openai server error (retry) + default: + // unhandled + } } ``` From 4b60aa16d6cea1520fe11d95deb6a98fa6667d55 Mon Sep 17 00:00:00 2001 From: Quest Henkart Date: Wed, 3 May 2023 12:18:06 +0800 Subject: [PATCH 5/6] read me --- README.md | 50 ++++++++++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 659e953b0..41fa2a913 100644 --- a/README.md +++ b/README.md @@ -52,30 +52,6 @@ func main() { ``` - -### Error handling: - -Open-AI maintains clear documentation on how to [handle API errors](https://platform.openai.com/docs/guides/error-codes/api-errors) - -example: -``` -e := &APIError{} -if errors.As(err, &e) { - switch e.HTTPStatusCode { - case 401: - // invalid auth or key (do not retry) - case 429: - // rate limiting or engine overload (wait and retry) - case 500: - // openai server error (retry) - default: - // unhandled - } -} - -``` - - ### Other examples:
@@ -484,3 +460,29 @@ func main() { } ```
+ +
+Error handling + +Open-AI maintains clear documentation on how to [handle API errors](https://platform.openai.com/docs/guides/error-codes/api-errors) + +example: +``` +e := &APIError{} +if errors.As(err, &e) { + switch e.HTTPStatusCode { + case 401: + // invalid auth or key (do not retry) + case 429: + // rate limiting or engine overload (wait and retry) + case 500: + // openai server error (retry) + default: + // unhandled + } +} + +``` +
+ + From 47cac6c009f5c1bf7da2a264e69af39672cb3812 Mon Sep 17 00:00:00 2001 From: Quest Henkart Date: Thu, 4 May 2023 01:04:26 +0800 Subject: [PATCH 6/6] add import to readme example --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 41fa2a913..f7e6990ae 100644 --- a/README.md +++ b/README.md @@ -468,7 +468,7 @@ Open-AI maintains clear documentation on how to [handle API errors](https://plat example: ``` -e := &APIError{} +e := &openai.APIError{} if errors.As(err, &e) { switch e.HTTPStatusCode { case 401: