// Code generated by @openmeter/typespec-go. DO NOT EDIT. package openmeter import ( "encoding/json" "errors" "fmt" ) // ErrEmptyID is returned by operations that target a single resource when the // resource ID is empty. It is caught before any request is made so an omitted // ID surfaces as a clear client-side error rather than an ambiguous server // response. Match it with errors.Is. var ErrEmptyID = errors.New("openmeter: resource ID must not be empty") // APIError is returned for any non-2xx API response. It mirrors the API's // RFC 7807-style problem body. When the body cannot be parsed as such, Title is // left empty and RawBody carries the undecoded payload. type APIError struct { // StatusCode is the HTTP status code of the response. StatusCode int `json:"-"` // Status is the status code echoed in the problem body (usually equal to // StatusCode). Status int `json:"status"` // Title is a short, stable, human-readable summary of the problem. Title string `json:"title"` // Type is an optional machine-readable error type. Type string `json:"type,omitempty"` // Detail is a human-readable explanation specific to this occurrence. Detail string `json:"detail"` // Instance carries the correlation ID, formatted as kong:trace:. Instance string `json:"instance"` // RawBody is the undecoded response body, always populated. RawBody []byte `json:"-"` } func newAPIError(statusCode int, body []byte) *APIError { e := &APIError{StatusCode: statusCode, RawBody: body} // Best-effort decode; a non-conforming body still yields a useful error via // StatusCode and RawBody. _ = json.Unmarshal(body, e) return e } // AsAPIError returns the APIError inside err, when err came from an API response. func AsAPIError(err error) (*APIError, bool) { var apiErr *APIError if errors.As(err, &apiErr) { return apiErr, true } return nil, false } // Decode decodes the original error response body into out. func (e *APIError) Decode(out any) error { return json.Unmarshal(e.RawBody, out) } // DecodeAPIError decodes an API error body into T. The returned boolean is false // when err is not an APIError. func DecodeAPIError[T any](err error) (T, bool, error) { var zero T apiErr, ok := AsAPIError(err) if !ok { return zero, false, nil } var out T if err := apiErr.Decode(&out); err != nil { return zero, true, err } return out, true, nil } func (e *APIError) Error() string { switch { case e.Title != "" && e.Detail != "": return fmt.Sprintf("openmeter: %d %s: %s", e.StatusCode, e.Title, e.Detail) case e.Title != "": return fmt.Sprintf("openmeter: %d %s", e.StatusCode, e.Title) default: // No RFC 7807 fields parsed (e.g. a proxy returned an HTML error page). // Inline the raw body for diagnostics but bound it so a large payload // can't blow up log lines; RawBody still holds the full response. const maxInline = 512 body := e.RawBody suffix := "" if len(body) > maxInline { body = body[:maxInline] suffix = "… (truncated)" } return fmt.Sprintf("openmeter: unexpected status %d: %s%s", e.StatusCode, string(body), suffix) } }