package errs import ( "context" "encoding/json" "errors" "github.com/zeromicro/go-zero/core/logx" "github.com/zeromicro/go-zero/rest" "github.com/zeromicro/go-zero/rest/httpx" "net/http" ) const JsonContentType = "application/json; charset=utf-8" func init() { httpx.SetErrorHandlerCtx(ErrorHandleCtx) httpx.SetErrorHandler(ErrorHandle) httpx.SetOkHandler(OkHandle) } func OkHandle(ctx context.Context, v any) any { return map[string]any{ "status": map[string]any{ "code": ErrSucceed, "msg": "ok", }, "data": v, } } func WithUnauthorizedCallback() rest.RunOption { return rest.WithUnauthorizedCallback(func(w http.ResponseWriter, r *http.Request, err error) { body := map[string]any{ "status": map[string]any{ "code": ErrUnauthorized, "msg": err.Error(), }, } data, _ := json.Marshal(body) w.Header().Set(httpx.ContentType, "application/json; charset=utf-8") w.WriteHeader(http.StatusOK) _, err = w.Write(data) if err != nil { logx.Errorw("error write response", logx.Field("type", "http"), logx.Field("error", err)) } }) } func ErrorHandle(err error) (int, any) { return ErrorHandleCtx(context.Background(), err) } func ErrorHandleCtx(ctx context.Context, err error) (int, any) { code := ErrUnknownReason var msg string if ec, ok := err.(interface{ Code() Reason }); ok { code = ec.Code() } if ec, ok := err.(interface{ Message() string }); ok { msg = ec.Message() } else { msg = err.Error() } if code < ErrUnknownReason && code >= ErrInternalServer { logx.Errorw("request system error", logx.Field("err-msg", msg)) msg = "system error" } body := map[string]any{ "status": map[string]any{ "code": code, "msg": msg, }, } return http.StatusOK, body } func WriteHttpResponse(ctx context.Context, w http.ResponseWriter, v any) { w.Header().Set(httpx.ContentType, JsonContentType) w.WriteHeader(http.StatusOK) body, err := json.Marshal(v) if err != nil { logx.WithContext(ctx).Errorw("error marshal response", logx.Field("error", err), logx.Field("value", v)) return } if n, err := w.Write(body); err != nil { // http.ErrHandlerTimeout has been handled by http.TimeoutHandler, // so it's ignored here. if !errors.Is(err, http.ErrHandlerTimeout) { logx.WithContext(ctx).Errorw("write response failed, error", logx.Field("error", err), logx.Field("value", v)) } } else if n < len(body) { logx.WithContext(ctx).Errorf("actual bytes: %d, written bytes: %d", len(body), n) } }