package apierrors import "encoding/json" // Snapshot contains only the resolved public error, suitable for replay // metadata. Parameters and internal causes are deliberately excluded. type Snapshot struct { Status int `json:"status"` Code string `json:"code"` Message string `json:"message"` BusinessCode any `json:"businessCode,omitempty"` } // Encode the public code as opaque JSON text so shared stores (including Redis // Lua/cjson) cannot round an int64 while rewriting their record envelopes. func (s Snapshot) MarshalJSON() ([]byte, error) { var encoded string if s.BusinessCode != nil { code, err := normalizeCatalogCode(s.BusinessCode) if err != nil { return nil, err } raw, err := json.Marshal(code) if err != nil { return nil, err } encoded = string(raw) } return json.Marshal(struct { Status int `json:"status"` Code string `json:"code"` Message string `json:"message"` BusinessCodeJSON string `json:"businessCodeJson,omitempty"` }{s.Status, s.Code, s.Message, encoded}) } func (s *Snapshot) UnmarshalJSON(data []byte) error { type plain Snapshot var out struct { plain BusinessCodeJSON string `json:"businessCodeJson,omitempty"` } if err := DecodeCatalogJSON(data, &out); err != nil { return err } if out.BusinessCodeJSON != "" { if err := DecodeCatalogJSON([]byte(out.BusinessCodeJSON), &out.BusinessCode); err != nil { return err } } if out.BusinessCode != nil { code, err := normalizeCatalogCode(out.BusinessCode) if err != nil { return err } out.BusinessCode = code } *s = Snapshot(out.plain) return nil } func (e *APIError) Snapshot() *Snapshot { if e == nil { return nil } return &Snapshot{Status: e.Status, Code: e.Code, Message: e.Message, BusinessCode: e.BusinessCode} } func (s *Snapshot) ErrorValue() *APIError { if s == nil { return nil } return &APIError{Status: s.Status, Code: s.Code, Message: s.Message, BusinessCode: s.BusinessCode} }