

新闻资讯
行业动态Go中处理API错误需统一分类、封装结构化响应并映射HTTP错误:定义APIError结构含code/status/message/details;用中间件统一处理panic和error;按4xx/5xx/业务错误语义化响应;集成validator聚合校验错误到details。
在 Go 中处理 API 调用错误并返回标准化响应,核心是统一错误分类、封装结构化响应体、并在 HTTP 层做一致的错误映射。不建议直接返回原始 error 或 panic,而应将错误转化为可预测的 JSON 响应(如 {"code": 400, "message": "invalid email", "details": {...}})。
创建一个可序列化的错误响应结构,包含状态码、业务码、用户提示和可选详情:
示例:
type APIError struct {
Code int `json:"code"` // HTTP 状态码(如 404)
Status string `json:"status"` // 如 "Not Found"
Message string `json:"message"` // 用户友好的提示
Details interface{} `json:"details,omitempty"`
}
func (e *APIError) Error() string { return e.Message }
// 快捷构造函数
func NewBadRequest(msg string, details ...interface{}) *APIError {
err := &APIError{
Code: http.StatusBadRequest,
Status: http.StatusText(http.StatusBadRequest),
Message: msg,
}
if len(details) > 0 && details[0] != nil {
err.Details = details[0]
}
return err
}
避免每个 handler 重复写 json.NewEncoder(w).Encode(...)。推荐使用中间件捕获 panic 和显式错误:
http.Handler 包装器,在 defer 中 recover panic,并转为 500 Internal Server Error
error(如 func(w http.ResponseWriter, r *http.Request) error),由包装器统一处理*APIError;是则按其 Code/Message 渲染;否则视为未预期错误,记录日志并返回 500不同错误应有明确归因,便于前端处理和监控:
validator 库)、缺失 header、格式错误 —— 用 NewBadRequest 或 NewUnauthorized
"user_not_found")放入 Details 字段,方
便前端分支处理对请求体(如 json)做结构化校验时,不要只返回第一个错误。用 github.com/go-playground/validator/v10 收集全部字段错误,再聚合进 APIError.Details:
type CreateUserRequest struct {
Email string `json:"email" validate:"required,email"`
Age int `json:"age" validate:"required,gte=0,lte=120"`
}
// 校验后
if err := validate.Struct(req); err != nil {
errs := make(map[string]string)
for _, e := range err.(validator.ValidationErrors) {
errs[e.Field()] = e.Tag() + " validation failed"
}
return NewBadRequest("validation failed", errs)
}