| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162 |
- package api
- import (
- "fmt"
- "strings"
- )
- // APIError is a task the gateway refused or could not complete.
- //
- // It carries the gateway's own code so the caller can react to a specific
- // failure (bad credentials, unknown zone, name server mismatch) without
- // matching on message text.
- type APIError struct {
- Code string
- Text string
- Object string
- Stid string
- }
- func (e *APIError) Error() string {
- var b strings.Builder
- if e.Code != "" {
- fmt.Fprintf(&b, "%s: %s", e.Code, e.Text)
- } else {
- b.WriteString(e.Text)
- }
- if e.Object != "" {
- fmt.Fprintf(&b, " (object: %s)", e.Object)
- }
- return b.String()
- }
- // fromResult builds an error from a failed result block. The actionable code
- // and text live in msg, not in status, so msg is preferred.
- func fromResult(r Result, stid string) *APIError {
- e := &APIError{Stid: stid}
- var pick *Msg
- for i := range r.Msg {
- m := &r.Msg[i]
- // A notification ("N") alongside an error ("E") is not the failure.
- if strings.EqualFold(m.Type, "error") || strings.HasPrefix(m.Code, "E") {
- pick = m
- break
- }
- if pick == nil {
- pick = m
- }
- }
- switch {
- case pick != nil && pick.Text != "":
- e.Code, e.Text = pick.Code, pick.Text
- case r.Status.Text != "":
- e.Code, e.Text = r.Status.Code, r.Status.Text
- default:
- e.Text = "the gateway reported a failure without a message"
- }
- if pick != nil && pick.Object != nil {
- e.Object = pick.Object.Type + " " + pick.Object.Value
- }
- return e
- }
|