116 lines
2.8 KiB
Go
116 lines
2.8 KiB
Go
package openai
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
// APIError provides error information returned by the OpenAI API.
|
|
// InnerError struct is only valid for Azure OpenAI Service.
|
|
type APIError struct {
|
|
Code any `json:"code,omitempty"`
|
|
Message string `json:"message"`
|
|
Param *string `json:"param,omitempty"`
|
|
Type string `json:"type"`
|
|
HTTPStatus string `json:"-"`
|
|
HTTPStatusCode int `json:"-"`
|
|
InnerError *InnerError `json:"innererror,omitempty"`
|
|
}
|
|
|
|
// InnerError Azure Content filtering. Only valid for Azure OpenAI Service.
|
|
type InnerError struct {
|
|
Code string `json:"code,omitempty"`
|
|
ContentFilterResults ContentFilterResults `json:"content_filter_result,omitempty"`
|
|
}
|
|
|
|
// RequestError provides information about generic request errors.
|
|
type RequestError struct {
|
|
HTTPStatus string
|
|
HTTPStatusCode int
|
|
Err error
|
|
Body []byte
|
|
}
|
|
|
|
type ErrorResponse struct {
|
|
Error *APIError `json:"error,omitempty"`
|
|
}
|
|
|
|
func (e *APIError) Error() string {
|
|
if e.HTTPStatusCode > 0 {
|
|
return fmt.Sprintf("error, status code: %d, status: %s, message: %s", e.HTTPStatusCode, e.HTTPStatus, e.Message)
|
|
}
|
|
|
|
return e.Message
|
|
}
|
|
|
|
func (e *APIError) UnmarshalJSON(data []byte) (err error) {
|
|
var rawMap map[string]json.RawMessage
|
|
err = json.Unmarshal(data, &rawMap)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
err = json.Unmarshal(rawMap["message"], &e.Message)
|
|
if err != nil {
|
|
// If the parameter field of a function call is invalid as a JSON schema
|
|
// refs: https://github.com/sashabaranov/go-openai/issues/381
|
|
var messages []string
|
|
err = json.Unmarshal(rawMap["message"], &messages)
|
|
if err != nil {
|
|
return
|
|
}
|
|
e.Message = strings.Join(messages, ", ")
|
|
}
|
|
|
|
// optional fields for azure openai
|
|
// refs: https://github.com/sashabaranov/go-openai/issues/343
|
|
if _, ok := rawMap["type"]; ok {
|
|
err = json.Unmarshal(rawMap["type"], &e.Type)
|
|
if err != nil {
|
|
return
|
|
}
|
|
}
|
|
|
|
if _, ok := rawMap["innererror"]; ok {
|
|
err = json.Unmarshal(rawMap["innererror"], &e.InnerError)
|
|
if err != nil {
|
|
return
|
|
}
|
|
}
|
|
|
|
// optional fields
|
|
if _, ok := rawMap["param"]; ok {
|
|
err = json.Unmarshal(rawMap["param"], &e.Param)
|
|
if err != nil {
|
|
return
|
|
}
|
|
}
|
|
|
|
if _, ok := rawMap["code"]; !ok {
|
|
return nil
|
|
}
|
|
|
|
// if the api returned a number, we need to force an integer
|
|
// since the json package defaults to float64
|
|
var intCode int
|
|
err = json.Unmarshal(rawMap["code"], &intCode)
|
|
if err == nil {
|
|
e.Code = intCode
|
|
return nil
|
|
}
|
|
|
|
return json.Unmarshal(rawMap["code"], &e.Code)
|
|
}
|
|
|
|
func (e *RequestError) Error() string {
|
|
return fmt.Sprintf(
|
|
"error, status code: %d, status: %s, message: %s, body: %s",
|
|
e.HTTPStatusCode, e.HTTPStatus, e.Err, e.Body,
|
|
)
|
|
}
|
|
|
|
func (e *RequestError) Unwrap() error {
|
|
return e.Err
|
|
}
|