package rs import ( "fmt" "net/http" "strings" ) var ( // ErrOK 表示没有任何错误。 // 对应 HTTP 响应状态码为 500。 ErrOK = NewError(http.StatusOK, 0, "OK") // ErrInternal 客户端请求有效,但服务器处理时发生了意外。 // 对应 HTTP 响应状态码为 500。 ErrInternal = NewError(http.StatusInternalServerError, -100, "系统内部错误") // ErrServiceUnavailable 服务器无法处理请求,一般用于网站维护状态。 // 对应 HTTP 响应状态码为 503。 ErrServiceUnavailable = NewError(http.StatusServiceUnavailable, -101, "服务不可用") // ErrUnauthorized 用户未提供身份验证凭据,或者没有通过身份验证。 // 响应的 HTTP 状态码为 401。 ErrUnauthorized = NewError(http.StatusUnauthorized, -102, "身份验证失败") // ErrForbidden 用户通过了身份验证,但是不具有访问资源所需的权限。 // 响应的 HTTP 状态码为 403。 ErrForbidden = NewError(http.StatusForbidden, -103, "不具有访问资源所需的权限") // ErrGone 所请求的资源已从这个地址转移,不再可用。 // 响应的 HTTP 状态码为 410。 ErrGone = NewError(http.StatusGone, -104, "所请求的资源不存在") // ErrUnsupportedMediaType 客户端要求的返回格式不支持。 // 比如,API 只能返回 JSON 格式,但是客户端要求返回 XML 格式。 // 响应的 HTTP 状态码为 415。 ErrUnsupportedMediaType = NewError(http.StatusUnsupportedMediaType, -105, "请求的数据格式错误") // ErrUnprocessableEntity 无法处理客户端上传的附件,导致请求失败。 // 响应的 HTTP 状态码为 422。 ErrUnprocessableEntity = NewError(http.StatusUnprocessableEntity, -106, "上传了不被支持的附件") // ErrTooManyRequests 客户端的请求次数超过限额。 // 响应的 HTTP 状态码为 429。 ErrTooManyRequests = NewError(http.StatusTooManyRequests, -107, "请求次数超过限额") // ErrSeeOther 表示需要参考另一个 URL 才能完成接收的请求操作, // 当请求方式使用 POST、PUT 和 DELETE 时,对应的 HTTP 状态码为 303, // 其它的请求方式在大多数情况下应该使用 400 状态码。 ErrSeeOther = NewError(http.StatusSeeOther, -108, "需要更进一步才能完成操作") // ErrBadRequest 服务器不理解客户端的请求。 // 对应 HTTP 状态码为 400。 ErrBadRequest = NewError(http.StatusBadRequest, -109, "请求错误") // ErrBadParams 客户端提交的参数不符合要求 // 对应 HTTP 状态码为 400。 ErrBadParams = NewError(http.StatusBadRequest, -110, "参数错误") // ErrRecordNotFound 访问的数据不存在 // 对应 HTTP 状态码为 404。 ErrRecordNotFound = NewError(http.StatusNotFound, -111, "访问的数据不存在") ) type Error struct { // 被包装的错误对象 internal error // 响应的 HTTP 状态码 status int // 错误码 code int // 错误提示消息 text string // 错误携带的响应数据 data any } func NewError(status, code int, text string) *Error { return &Error{nil, status, code, text, nil} } // Code 返回错误码 func (e *Error) Code() int { return e.code } // Text 返回错误提示 func (e *Error) Text() string { return e.text } // Data 返回携带的数据 func (e *Error) Data() any { return e.data } // Internal 返回原始错误 func (e *Error) Internal() error { return e.internal } // Unwrap 支持 errors.Unwrap() 方法 func (e *Error) Unwrap() error { return e.Internal() } // WithInternal 通过实际错误对象派生新的实例 func (e *Error) WithInternal(err error) *Error { // 由于错误比较复杂,不好做完全等于, // 在这里就直接复制当前对象 c := *e c.internal = err return &c } // WithStatus 通过 HTTP 状态码派生新的实例 func (e *Error) WithStatus(status int) *Error { if e.status != status { c := *e c.status = status return &c } return e } // WithText 通过新的错误提示派生新的实例 func (e *Error) WithText(text string) *Error { if text != e.text { c := *e c.text = text return &c } return e } // WithData 通过携带数据派生新的实例 func (e *Error) WithData(data any) *Error { if e.data != data { c := *e c.data = data return &c } return e } // String 实现 fmt.Stringer 接口 func (e *Error) String() string { return strings.TrimSpace(fmt.Sprintf("%d %s", e.code, e.text)) } // Error 实现错误接口 func (e *Error) Error() string { return e.String() }