package errors import ( "fmt" "net/http" ) // ErrorCode 错误码 type ErrorCode int const ( // 成功 ErrOK ErrorCode = iota // 通用错误 (1000-1999) ErrInternalError ErrInvalidRequest ErrNotImplemented // 数据库错误 (2000-2999) ErrDatabaseError ErrCollectionNotFound ErrDocumentNotFound ErrDuplicateKey ErrWriteConflict ErrReadConflict // 查询错误 (3000-3999) ErrQueryParseError ErrQueryExecutionError ErrInvalidOperator ErrInvalidExpression ErrTypeMismatch // 聚合错误 (4000-4999) ErrAggregationError ErrPipelineError ErrStageError ErrGroupError ErrSortError // 索引错误 (5000-5999) ErrIndexError ErrIndexNotFound ErrIndexOptionsError // 事务错误 (6000-6999) ErrTransactionError ErrTransactionAbort ErrTransactionCommit // 认证授权错误 (7000-7999) ErrAuthenticationError ErrAuthorizationError ErrPermissionDenied // 资源错误 (8000-8999) ErrResourceNotFound ErrResourceExhausted ErrTimeout ErrUnavailable ) // GomogError Gomog 错误类型 type GomogError struct { Code ErrorCode `json:"code"` Message string `json:"message"` Details string `json:"details,omitempty"` Cause error `json:"-"` Metadata map[string]string `json:"metadata,omitempty"` HTTPStatus int `json:"-"` } func (e *GomogError) Error() string { if e.Cause != nil { return fmt.Sprintf("[%d] %s: %v", e.Code, e.Message, e.Cause) } if e.Details != "" { return fmt.Sprintf("[%d] %s: %s", e.Code, e.Message, e.Details) } return fmt.Sprintf("[%d] %s", e.Code, e.Message) } func (e *GomogError) Unwrap() error { return e.Cause } // WithDetails 添加详细信息 func (e *GomogError) WithDetails(details string) *GomogError { e.Details = details return e } // WithMetadata 添加元数据 func (e *GomogError) WithMetadata(key, value string) *GomogError { if e.Metadata == nil { e.Metadata = make(map[string]string) } e.Metadata[key] = value return e } // WithHTTPStatus 设置 HTTP 状态码 func (e *GomogError) WithHTTPStatus(status int) *GomogError { e.HTTPStatus = status return e } // GetHTTPStatus 获取 HTTP 状态码 func (e *GomogError) GetHTTPStatus() int { if e.HTTPStatus != 0 { return e.HTTPStatus } // 根据错误码返回默认 HTTP 状态码 switch e.Code { case ErrOK: return http.StatusOK case ErrInternalError, ErrDatabaseError, ErrAggregationError: return http.StatusInternalServerError case ErrInvalidRequest, ErrQueryParseError, ErrInvalidOperator, ErrTypeMismatch: return http.StatusBadRequest case ErrCollectionNotFound, ErrDocumentNotFound, ErrResourceNotFound: return http.StatusNotFound case ErrDuplicateKey, ErrWriteConflict: return http.StatusConflict case ErrPermissionDenied, ErrAuthorizationError: return http.StatusForbidden case ErrAuthenticationError: return http.StatusUnauthorized case ErrTimeout: return http.StatusRequestTimeout case ErrUnavailable: return http.StatusServiceUnavailable default: return http.StatusInternalServerError } } // 预定义错误 - 通用错误 (1000-1999) var ( ErrInternal = &GomogError{Code: ErrInternalError, Message: "internal error"} ErrInvalidReq = &GomogError{Code: ErrInvalidRequest, Message: "invalid request"} ErrNotImpl = &GomogError{Code: ErrNotImplemented, Message: "not implemented"} ) // 预定义错误 - 数据库错误 (2000-2999) var ( ErrCollectionNotFnd = &GomogError{Code: ErrCollectionNotFound, Message: "collection not found"} ErrDocumentNotFnd = &GomogError{Code: ErrDocumentNotFound, Message: "document not found"} ErrDuplicate = &GomogError{Code: ErrDuplicateKey, Message: "duplicate key"} ErrDatabase = &GomogError{Code: ErrDatabaseError, Message: "database error"} ErrWriteConf = &GomogError{Code: ErrWriteConflict, Message: "write conflict"} ErrReadConf = &GomogError{Code: ErrReadConflict, Message: "read conflict"} ) // 预定义错误 - 查询错误 (3000-3999) var ( ErrQueryParse = &GomogError{Code: ErrQueryParseError, Message: "query parse error"} ErrQueryExec = &GomogError{Code: ErrQueryExecutionError, Message: "query execution error"} ErrInvalidOp = &GomogError{Code: ErrInvalidOperator, Message: "invalid operator"} ErrInvalidExpr = &GomogError{Code: ErrInvalidExpression, Message: "invalid expression"} ErrTypeMis = &GomogError{Code: ErrTypeMismatch, Message: "type mismatch"} ) // 预定义错误 - 聚合错误 (4000-4999) var ( ErrAggregation = &GomogError{Code: ErrAggregationError, Message: "aggregation error"} ErrPipeline = &GomogError{Code: ErrPipelineError, Message: "pipeline error"} ErrStage = &GomogError{Code: ErrStageError, Message: "stage error"} ErrGroup = &GomogError{Code: ErrGroupError, Message: "group error"} ErrSort = &GomogError{Code: ErrSortError, Message: "sort error"} ) // 预定义错误 - 索引错误 (5000-5999) var ( ErrIndex = &GomogError{Code: ErrIndexError, Message: "index error"} ErrIndexNotFnd = &GomogError{Code: ErrIndexNotFound, Message: "index not found"} ErrIndexOpts = &GomogError{Code: ErrIndexOptionsError, Message: "index options error"} ) // 预定义错误 - 事务错误 (6000-6999) var ( ErrTransaction = &GomogError{Code: ErrTransactionError, Message: "transaction error"} ErrTransAbort = &GomogError{Code: ErrTransactionAbort, Message: "transaction aborted"} ErrTransCommit = &GomogError{Code: ErrTransactionCommit, Message: "transaction commit error"} ) // 预定义错误 - 认证授权错误 (7000-7999) var ( ErrAuthentication = &GomogError{Code: ErrAuthenticationError, Message: "authentication error"} ErrAuthorization = &GomogError{Code: ErrAuthorizationError, Message: "authorization error"} ErrPermDenied = &GomogError{Code: ErrPermissionDenied, Message: "permission denied"} ) // 预定义错误 - 资源错误 (8000-8999) var ( ErrResourceNotFnd = &GomogError{Code: ErrResourceNotFound, Message: "resource not found"} ErrResourceExhaust = &GomogError{Code: ErrResourceExhausted, Message: "resource exhausted"} ErrTimeoutErr = &GomogError{Code: ErrTimeout, Message: "timeout"} ErrUnavailableErr = &GomogError{Code: ErrUnavailable, Message: "service unavailable"} ) // New 创建新错误 func New(code ErrorCode, message string) *GomogError { return &GomogError{ Code: code, Message: message, } } // Newf 创建带格式化的新错误 func Newf(code ErrorCode, format string, args ...interface{}) *GomogError { return &GomogError{ Code: code, Message: fmt.Sprintf(format, args...), } } // Wrap 包装错误 func Wrap(err error, code ErrorCode, message string) *GomogError { return &GomogError{ Code: code, Message: message, Cause: err, } } // Wrapf 包装错误并添加格式化消息 func Wrapf(err error, code ErrorCode, format string, args ...interface{}) *GomogError { return &GomogError{ Code: code, Message: fmt.Sprintf(format, args...), Cause: err, } } // Is 判断错误是否为目标类型 func (e *GomogError) Is(target error) bool { if te, ok := target.(*GomogError); ok { return e.Code == te.Code } return false } // IsCollectionNotFound 判断是否是集合不存在错误 func IsCollectionNotFound(err error) bool { if e, ok := err.(*GomogError); ok { return e.Code == ErrCollectionNotFound } return false } // IsDocumentNotFound 判断是否是文档不存在错误 func IsDocumentNotFound(err error) bool { if e, ok := err.(*GomogError); ok { return e.Code == ErrDocumentNotFound } return false } // IsDuplicateKey 判断是否是重复键错误 func IsDuplicateKey(err error) bool { if e, ok := err.(*GomogError); ok { return e.Code == ErrDuplicateKey } return false } // IsInvalidRequest 判断是否是无效请求错误 func IsInvalidRequest(err error) bool { if e, ok := err.(*GomogError); ok { return e.Code == ErrInvalidRequest } return false } // IsTypeMismatch 判断是否是类型不匹配错误 func IsTypeMismatch(err error) bool { if e, ok := err.(*GomogError); ok { return e.Code == ErrTypeMismatch } return false } // IsTimeout 判断是否是超时错误 func IsTimeout(err error) bool { if e, ok := err.(*GomogError); ok { return e.Code == ErrTimeout } return false } // GetErrorCode 获取错误码 func GetErrorCode(err error) ErrorCode { if e, ok := err.(*GomogError); ok { return e.Code } return ErrInternalError } // GetErrorMessage 获取错误消息 func GetErrorMessage(err error) string { if e, ok := err.(*GomogError); ok { return e.Message } return err.Error() } // ToHTTPStatus 将错误转换为 HTTP 状态码 func ToHTTPStatus(err error) int { if e, ok := err.(*GomogError); ok { return e.GetHTTPStatus() } return http.StatusInternalServerError } // Equal 判断两个错误是否相等 func Equal(err1, err2 error) bool { if e1, ok := err1.(*GomogError); ok { if e2, ok := err2.(*GomogError); ok { return e1.Code == e2.Code && e1.Message == e2.Message } } return err1 == err2 }