107 lines
2.4 KiB
Go
107 lines
2.4 KiB
Go
package reply
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
|
|
"spark-server/internal/pkg/errs"
|
|
"spark-server/internal/pkg/i18n"
|
|
"spark-server/internal/pkg/reqctx"
|
|
)
|
|
|
|
// Envelope is the unified HTTP and TCP response body: {"code":"","msg":"","request_id":"","data":{}}.
|
|
type Envelope struct {
|
|
Code string `json:"code"`
|
|
Msg string `json:"msg"`
|
|
RequestID string `json:"request_id"`
|
|
Data json.RawMessage `json:"data"`
|
|
}
|
|
|
|
func Stamp(ctx context.Context, env Envelope) Envelope {
|
|
return StampID(env, reqctx.RequestID(ctx))
|
|
}
|
|
|
|
func StampID(env Envelope, requestID string) Envelope {
|
|
env.RequestID = requestID
|
|
return env
|
|
}
|
|
|
|
func OK(data any) Envelope {
|
|
return Envelope{Code: errs.OK.Code, Msg: errs.OK.Msg, Data: marshalData(data)}
|
|
}
|
|
|
|
func Fail(code, msg string) Envelope {
|
|
if code == "" {
|
|
code = errs.ErrInner.Code
|
|
}
|
|
if msg == "" {
|
|
msg = errs.ErrInner.Msg
|
|
}
|
|
return Envelope{Code: code, Msg: msg, Data: json.RawMessage("{}")}
|
|
}
|
|
|
|
func FailData(code, msg string, data any) Envelope {
|
|
env := Fail(code, msg)
|
|
env.Data = marshalData(data)
|
|
return env
|
|
}
|
|
|
|
func FromError(err error) Envelope {
|
|
return FromErrorLang(i18n.Default, err)
|
|
}
|
|
|
|
func FromContext(ctx context.Context, err error) Envelope {
|
|
return Stamp(ctx, FromErrorLang(reqctx.Lang(ctx), err))
|
|
}
|
|
|
|
func FromErrorLang(lang i18n.Lang, err error) Envelope {
|
|
if err == nil {
|
|
return OK(nil)
|
|
}
|
|
if app, ok := errs.AsAppError(err); ok {
|
|
return Fail(app.Code, publicMsg(lang, app))
|
|
}
|
|
return Fail(errs.ErrInner.Code, i18n.ErrorMsg(lang, errs.ErrInner.Code))
|
|
}
|
|
|
|
func publicMsg(lang i18n.Lang, app *errs.AppError) string {
|
|
if app.CustomMsg() {
|
|
return app.Msg
|
|
}
|
|
return i18n.ErrorMsg(lang, app.Code)
|
|
}
|
|
|
|
func Marshal(env Envelope) ([]byte, error) {
|
|
return json.Marshal(env)
|
|
}
|
|
|
|
func MustMarshal(env Envelope) []byte {
|
|
b, err := Marshal(env)
|
|
if err != nil {
|
|
b, _ = json.Marshal(Fail(errs.ErrInner.Code, errs.ErrInner.Msg))
|
|
}
|
|
return b
|
|
}
|
|
|
|
func Unmarshal(body []byte) (Envelope, error) {
|
|
var env Envelope
|
|
if err := json.Unmarshal(body, &env); err != nil {
|
|
return Envelope{}, errs.ErrInvalidFrame.WithInnerMsg(err.Error())
|
|
}
|
|
if len(env.Data) == 0 {
|
|
env.Data = json.RawMessage("{}")
|
|
}
|
|
return env, nil
|
|
}
|
|
|
|
func marshalData(data any) json.RawMessage {
|
|
if data == nil {
|
|
return json.RawMessage("{}")
|
|
}
|
|
b, err := json.Marshal(data)
|
|
if err != nil || len(b) == 0 || string(b) == "null" {
|
|
return json.RawMessage("{}")
|
|
}
|
|
return b
|
|
}
|