170 lines
3.5 KiB
Go
170 lines
3.5 KiB
Go
package errors
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"net/http"
|
|
|
|
"haixun-backend/internal/library/errors/code"
|
|
)
|
|
|
|
type Error struct {
|
|
scope code.Scope
|
|
category code.Category
|
|
detail code.Detail
|
|
message string
|
|
cause error
|
|
}
|
|
|
|
func New(scope code.Scope, category code.Category, detail code.Detail, message string) *Error {
|
|
return &Error{scope: scope, category: category, detail: detail, message: message}
|
|
}
|
|
|
|
func FromError(err error) *Error {
|
|
var e *Error
|
|
if errors.As(err, &e) {
|
|
return e
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (e *Error) Error() string {
|
|
if e == nil {
|
|
return ""
|
|
}
|
|
return e.message
|
|
}
|
|
|
|
func (e *Error) Unwrap() error {
|
|
if e == nil {
|
|
return nil
|
|
}
|
|
return e.cause
|
|
}
|
|
|
|
func (e *Error) WithCause(cause error) *Error {
|
|
if e == nil {
|
|
return nil
|
|
}
|
|
cp := *e
|
|
cp.cause = cause
|
|
return &cp
|
|
}
|
|
|
|
func (e *Error) Scope() code.Scope {
|
|
if e == nil {
|
|
return code.Unset
|
|
}
|
|
return e.scope
|
|
}
|
|
|
|
func (e *Error) Category() code.Category {
|
|
if e == nil {
|
|
return code.SysInternal
|
|
}
|
|
return e.category
|
|
}
|
|
|
|
func (e *Error) Detail() code.Detail {
|
|
if e == nil {
|
|
return code.DefaultDetail
|
|
}
|
|
return e.detail
|
|
}
|
|
|
|
func (e *Error) Code() uint32 {
|
|
if e == nil {
|
|
return 0
|
|
}
|
|
return uint32(e.scope)*code.ScopeMultiplier + uint32(e.category)*code.CategoryMultiplier + uint32(e.detail)
|
|
}
|
|
|
|
func (e *Error) DisplayCode() string {
|
|
if e == nil {
|
|
return "00000000"
|
|
}
|
|
return fmt.Sprintf("%08d", e.Code())
|
|
}
|
|
|
|
func (e *Error) HTTPStatus() int {
|
|
if e == nil {
|
|
return http.StatusInternalServerError
|
|
}
|
|
switch e.category {
|
|
case code.InputInvalidFormat, code.InputMissingRequired:
|
|
return http.StatusBadRequest
|
|
case code.DBUnavailable:
|
|
return http.StatusServiceUnavailable
|
|
case code.ResNotFound:
|
|
return http.StatusNotFound
|
|
case code.ResConflict:
|
|
return http.StatusConflict
|
|
case code.ResInvalidState:
|
|
return http.StatusConflict
|
|
case code.AuthUnauthorized:
|
|
return http.StatusUnauthorized
|
|
case code.AuthForbidden:
|
|
return http.StatusForbidden
|
|
case code.SvcThirdParty:
|
|
return http.StatusBadGateway
|
|
default:
|
|
return http.StatusInternalServerError
|
|
}
|
|
}
|
|
|
|
type Builder struct {
|
|
scope code.Scope
|
|
}
|
|
|
|
func For(scope code.Scope) Builder {
|
|
return Builder{scope: scope}
|
|
}
|
|
|
|
func (b Builder) InputInvalidFormat(message string) *Error {
|
|
return New(b.scope, code.InputInvalidFormat, 0, message)
|
|
}
|
|
|
|
func (b Builder) InputMissingRequired(message string) *Error {
|
|
return New(b.scope, code.InputMissingRequired, 0, message)
|
|
}
|
|
|
|
func (b Builder) DBError(message string) *Error {
|
|
return New(b.scope, code.DBError, 0, message)
|
|
}
|
|
|
|
func (b Builder) DBUnavailable(message string) *Error {
|
|
return New(b.scope, code.DBUnavailable, 0, message)
|
|
}
|
|
|
|
func (b Builder) ResNotFound(message string) *Error {
|
|
return New(b.scope, code.ResNotFound, 0, message)
|
|
}
|
|
|
|
func (b Builder) ResConflict(message string) *Error {
|
|
return New(b.scope, code.ResConflict, 0, message)
|
|
}
|
|
|
|
func (b Builder) ResInvalidState(message string) *Error {
|
|
return New(b.scope, code.ResInvalidState, 0, message)
|
|
}
|
|
|
|
func (b Builder) AuthUnauthorized(message string) *Error {
|
|
return New(b.scope, code.AuthUnauthorized, 0, message)
|
|
}
|
|
|
|
func (b Builder) AuthForbidden(message string) *Error {
|
|
return New(b.scope, code.AuthForbidden, 0, message)
|
|
}
|
|
|
|
func (b Builder) SysInternal(message string) *Error {
|
|
return New(b.scope, code.SysInternal, 0, message)
|
|
}
|
|
|
|
func (b Builder) SysNotImplemented(message string) *Error {
|
|
return New(b.scope, code.SysNotImplemented, 0, message)
|
|
}
|
|
|
|
func (b Builder) SvcThirdParty(message string) *Error {
|
|
return New(b.scope, code.SvcThirdParty, 0, message)
|
|
}
|