Skip to content

Commit 8357b48

Browse files
chore: better err messaging
1 parent 267a09e commit 8357b48

1 file changed

Lines changed: 28 additions & 3 deletions

File tree

internal/api/types.go

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import (
44
"encoding/json"
55
"fmt"
66
"net/http"
7+
"sort"
8+
"strings"
79
)
810

911
// APIError is a structured error returned by the CreateOS API.
@@ -31,17 +33,40 @@ func (e *APIError) Hint() string {
3133
}
3234

3335
// ParseAPIError extracts a human-readable message from an API error response body.
36+
//
37+
// JSend "fail" bodies can shape `data` three different ways:
38+
//
39+
// "data": "shape is required" // plain string
40+
// "data": {"shape": "shape \"x\" not allowed..."} // field-error object
41+
// "data": {"auth": "invalid api key"} // single-field gate
42+
//
43+
// We try each in order and join field-error values into one human line so
44+
// the user actually sees what's wrong instead of "request failed with status 403".
3445
func ParseAPIError(statusCode int, body []byte) *APIError {
3546
var envelope struct {
3647
Data json.RawMessage `json:"data"`
3748
}
3849
msg := ""
39-
if err := json.Unmarshal(body, &envelope); err == nil {
40-
// data may be a plain string or an object
50+
if err := json.Unmarshal(body, &envelope); err == nil && len(envelope.Data) > 0 {
51+
// 1. plain string
4152
var s string
42-
if err := json.Unmarshal(envelope.Data, &s); err == nil {
53+
if err := json.Unmarshal(envelope.Data, &s); err == nil && s != "" {
4354
msg = s
4455
}
56+
// 2. field-error map { "field": "msg", ... }
57+
if msg == "" {
58+
var fields map[string]string
59+
if err := json.Unmarshal(envelope.Data, &fields); err == nil && len(fields) > 0 {
60+
parts := make([]string, 0, len(fields))
61+
for _, v := range fields {
62+
if v != "" {
63+
parts = append(parts, v)
64+
}
65+
}
66+
sort.Strings(parts)
67+
msg = strings.Join(parts, "; ")
68+
}
69+
}
4570
}
4671
if msg == "" {
4772
msg = fmt.Sprintf("request failed with status %d", statusCode)

0 commit comments

Comments
 (0)