72 lines
2.0 KiB
Go
72 lines
2.0 KiB
Go
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}
|
|
}
|