| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- package response
- import (
- "context"
- "errors"
- "net/http"
- "os"
- "github.com/zeromicro/go-zero/core/logx"
- "github.com/zeromicro/go-zero/rest/httpx"
- "go.opentelemetry.io/otel/trace"
- )
- // Body 是统一 HTTP 响应体,格式与前端 API.Result<T> 对齐:
- // 成功:{ "success": true, "data": ... }
- // 失败:{ "success": false, "errorCode": N, "errorMessage": "...", "showType": N }
- type Body struct {
- Success bool `json:"success"`
- Data interface{} `json:"data,omitempty"`
- ErrorCode int `json:"errorCode,omitempty"`
- ErrorMessage string `json:"errorMessage,omitempty"`
- ShowType int `json:"showType,omitempty"`
- TraceId string `json:"traceId,omitempty"`
- Host string `json:"host,omitempty"`
- }
- // ShowType 与前端 ErrorShowType 枚举对齐
- const (
- ShowTypeSilent = 0 // SILENT
- ShowTypeWarnMessage = 1 // WARN_MESSAGE
- ShowTypeErrorMessage = 2 // ERROR_MESSAGE
- ShowTypeNotification = 4 // NOTIFICATION
- ShowTypeRedirect = 9 // REDIRECT
- )
- var hostname string
- func init() {
- hostname, _ = os.Hostname()
- }
- type CodeError struct {
- code int
- msg string
- showType int
- }
- func NewCodeError(code int, msg string) *CodeError {
- return &CodeError{code: code, msg: msg, showType: ShowTypeErrorMessage}
- }
- func (e *CodeError) Error() string { return e.msg }
- func (e *CodeError) Code() int { return e.code }
- func (e *CodeError) ShowType() int { return e.showType }
- func ErrBadRequest(msg string) *CodeError { return NewCodeError(400, msg) }
- func ErrUnauthorized(msg string) *CodeError { return NewCodeError(401, msg) }
- func ErrForbidden(msg string) *CodeError { return NewCodeError(403, msg) }
- func ErrNotFound(msg string) *CodeError { return NewCodeError(404, msg) }
- func ErrConflict(msg string) *CodeError { return NewCodeError(409, msg) }
- func ErrTooManyRequests(msg string) *CodeError { return NewCodeError(429, msg) }
- func traceIdFromCtx(ctx context.Context) string {
- if sc := trace.SpanFromContext(ctx).SpanContext(); sc.IsValid() {
- return sc.TraceID().String()
- }
- return ""
- }
- func Setup() {
- httpx.SetOkHandler(func(_ context.Context, v any) any {
- if v == nil {
- return Body{Success: true, Host: hostname}
- }
- return Body{Success: true, Data: v, Host: hostname}
- })
- httpx.SetErrorHandlerCtx(func(ctx context.Context, err error) (int, any) {
- traceId := traceIdFromCtx(ctx)
- var ce *CodeError
- if errors.As(err, &ce) {
- return http.StatusOK, Body{
- Success: false,
- ErrorCode: ce.Code(),
- ErrorMessage: ce.Error(),
- ShowType: ce.ShowType(),
- TraceId: traceId,
- Host: hostname,
- }
- }
- logx.WithContext(ctx).Errorf("internal error: %+v", err)
- return http.StatusOK, Body{
- Success: false,
- ErrorCode: 500,
- ErrorMessage: "服务器内部错误",
- ShowType: ShowTypeErrorMessage,
- TraceId: traceId,
- Host: hostname,
- }
- })
- }
|