Files
go-omni/errors/snapshot.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}
}