Files
garage-ui/backend/internal/apierr/parse.go
T

54 lines
1.4 KiB
Go

package apierr
import (
"encoding/json"
"io"
"github.com/Noooste/azuretls-client"
)
// garageErrBody mirrors Garage's JSON error envelope.
type garageErrBody struct {
Code string `json:"code"`
Message string `json:"message"`
Region string `json:"region"`
Path string `json:"path"`
}
// ParseGarage returns nil for 2xx responses. For non-2xx it reads the body
// once, JSON-decodes the structured Garage error envelope, and returns a
// *UpstreamError. Malformed bodies are preserved verbatim in Message.
//
// ParseGarage DOES NOT close resp.RawBody on the success path — callers that
// decode the success body (decodeResponse in services/admin.go) still need
// access and are responsible for closing. On the error path the body is fully
// consumed before return.
func ParseGarage(resp *azuretls.Response) error {
if resp.StatusCode >= 200 && resp.StatusCode < 300 {
return nil
}
bodyBytes, _ := io.ReadAll(resp.RawBody)
ue := &UpstreamError{
HTTPStatus: resp.StatusCode,
Source: "garage",
}
var parsed garageErrBody
if len(bodyBytes) > 0 && json.Unmarshal(bodyBytes, &parsed) == nil && parsed.Code != "" {
ue.Code = parsed.Code
ue.Message = parsed.Message
ue.Details = map[string]string{}
if parsed.Region != "" {
ue.Details["region"] = parsed.Region
}
if parsed.Path != "" {
ue.Details["path"] = parsed.Path
}
} else {
ue.Message = string(bodyBytes)
}
return ue
}