| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 |
- // Package response provides the unified response envelope {code, message, data}
- // returned by every endpoint of this service.
- package response
- import (
- "context"
- "errors"
- "net/http"
- "strings"
- "udeServer/internal/apierr"
- "github.com/zeromicro/go-zero/rest/httpx"
- )
- // Business codes carried in the unified response body.
- const (
- CodeOK = 100000
- CodeBadRequest = 100001
- CodeNotFound = 100002
- CodeServerError = 100003
- )
- // MsgOK is the message of every successful response.
- const MsgOK = "操作成功"
- // Body is the unified response envelope.
- type Body struct {
- Code int `json:"code"`
- Message string `json:"message"`
- Data any `json:"data"`
- }
- // OK builds a successful response body.
- func OK(data any) Body {
- return Body{Code: CodeOK, Message: MsgOK, Data: data}
- }
- // Register installs the global success and error handlers on the framework,
- // so every endpoint response is wrapped in the unified envelope:
- // - success: HTTP 200 + {"code":100000,...,"data":<resp>}
- // - failure: HTTP 200 + {"code":100xxx,...,"data":null}
- func Register() {
- httpx.SetOkHandler(func(_ context.Context, data any) any {
- return OK(data)
- })
- // HTTP status is always 200; the client decides by body code only.
- httpx.SetErrorHandler(func(err error) (int, any) {
- return http.StatusOK, Body{
- Code: Code(err),
- Message: err.Error(),
- Data: nil,
- }
- })
- }
- // Code maps an error to its business code. Errors without an HTTP-aware
- // status, e.g. failures from the framework request parser, fall back to
- // CodeServerError unless they describe a missing/unset field.
- func Code(err error) int {
- var apiErr *apierr.Error
- if errors.As(err, &apiErr) {
- return statusToCode(apiErr.Status)
- }
- // The request parser reports missing required fields as a plain error
- // like `field "name" is not set` (core/mapping/unmarshaler.go), which is
- // a client-side problem rather than a server error.
- if strings.HasSuffix(err.Error(), " is not set") {
- return CodeBadRequest
- }
- return CodeServerError
- }
- // statusToCode maps the HTTP-aware status of apierr.Error to the body code.
- func statusToCode(status int) int {
- switch status {
- case http.StatusBadRequest:
- return CodeBadRequest
- case http.StatusNotFound:
- return CodeNotFound
- default:
- return CodeServerError
- }
- }
|