-
Notifications
You must be signed in to change notification settings - Fork 1
/
errors.go
63 lines (53 loc) · 1.3 KB
/
errors.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package client
import (
"encoding/json"
"fmt"
"net/http"
"strings"
)
// ResponseError represents an error response from the API.
type ResponseError struct {
StatusCode int
Message string
Details map[string]any
}
// Error satisfies the error interface.
func (re *ResponseError) Error() string {
b := new(strings.Builder)
if re.Message == "" {
_, _ = fmt.Fprintf(b, "unexpected response status: %d", re.StatusCode)
} else {
_, _ = b.WriteString(re.Message)
}
if traceID := re.TraceID(); traceID != "" {
_, _ = fmt.Fprintf(b, " (trace id: %s)", traceID)
}
return b.String()
}
// TraceID returns the identifier that can be given to Gradient Labs technical
// support to investigate an error.
func (re *ResponseError) TraceID() string {
if re.Details == nil {
return ""
}
traceID, ok := re.Details["trace_id"].(string)
if !ok {
return ""
}
return traceID
}
func responseError(rsp *http.Response) *ResponseError {
if rsp.StatusCode < 200 || rsp.StatusCode > 299 {
re := &ResponseError{StatusCode: rsp.StatusCode}
var payload struct {
Message string `json:"message"`
Details map[string]any `json:"details"`
}
if err := json.NewDecoder(rsp.Body).Decode(&payload); err == nil {
re.Message = payload.Message
re.Details = payload.Details
}
return re
}
return nil
}