132 lines
2.8 KiB
Go
132 lines
2.8 KiB
Go
package errors
|
||
|
||
import (
|
||
stderrors "errors"
|
||
"fmt"
|
||
"strings"
|
||
)
|
||
|
||
// WrapIfErr 如果 err 不为 nil,则包装错误并返回,否则返回 nil
|
||
func WrapIfErr(err error, errType, message string, code int) error {
|
||
if err == nil {
|
||
return nil
|
||
}
|
||
return Wrap(err, errType, message, code)
|
||
}
|
||
|
||
// JoinErrors 将多个错误合并为一个错误
|
||
// 如果只有一个错误不为 nil,则返回该错误
|
||
// 如果有多个错误不为 nil,则创建一个包含所有错误信息的新错误
|
||
func JoinErrors(errs ...error) error {
|
||
var nonNilErrs []error
|
||
for _, err := range errs {
|
||
if err != nil {
|
||
nonNilErrs = append(nonNilErrs, err)
|
||
}
|
||
}
|
||
|
||
if len(nonNilErrs) == 0 {
|
||
return nil
|
||
}
|
||
|
||
if len(nonNilErrs) == 1 {
|
||
return nonNilErrs[0]
|
||
}
|
||
|
||
// 合并多个错误
|
||
var messages []string
|
||
for _, err := range nonNilErrs {
|
||
messages = append(messages, err.Error())
|
||
}
|
||
|
||
return Internal(
|
||
fmt.Sprintf("multiple errors occurred: %s", strings.Join(messages, "; ")),
|
||
nonNilErrs[0],
|
||
)
|
||
}
|
||
|
||
// IsNil 检查错误是否为 nil
|
||
func IsNil(err error) bool {
|
||
return err == nil
|
||
}
|
||
|
||
// IsNotNil 检查错误是否不为 nil
|
||
func IsNotNil(err error) bool {
|
||
return err != nil
|
||
}
|
||
|
||
// IsType 检查错误是否为指定类型
|
||
func IsType(err error, errType string) bool {
|
||
return Is(err, errType)
|
||
}
|
||
|
||
// HasCause 检查错误是否包含指定的原因
|
||
func HasCause(err error, cause error) bool {
|
||
if err == nil || cause == nil {
|
||
return false
|
||
}
|
||
|
||
var appErr *AppError
|
||
if stderrors.As(err, &appErr) {
|
||
if appErr.Cause == cause {
|
||
return true
|
||
}
|
||
return HasCause(appErr.Cause, cause)
|
||
}
|
||
|
||
return err == cause
|
||
}
|
||
|
||
// AsAppError 将错误转换为 AppError 类型
|
||
func AsAppError(err error) (*AppError, bool) {
|
||
var appErr *AppError
|
||
if stderrors.As(err, &appErr) {
|
||
return appErr, true
|
||
}
|
||
return nil, false
|
||
}
|
||
|
||
// FormatErrorChain 格式化错误链,便于调试
|
||
func FormatErrorChain(err error) string {
|
||
if err == nil {
|
||
return "<nil>"
|
||
}
|
||
|
||
var result strings.Builder
|
||
result.WriteString(err.Error())
|
||
|
||
// 获取 AppError 类型的堆栈信息
|
||
var appErr *AppError
|
||
if stderrors.As(err, &appErr) && len(appErr.Stack) > 0 {
|
||
result.WriteString("\nStack Trace:\n")
|
||
for _, frame := range appErr.Stack {
|
||
result.WriteString(" ")
|
||
result.WriteString(frame)
|
||
result.WriteString("\n")
|
||
}
|
||
}
|
||
|
||
// 递归处理错误链
|
||
cause := stderrors.Unwrap(err)
|
||
if cause != nil {
|
||
result.WriteString("\nCaused by: ")
|
||
result.WriteString(FormatErrorChain(cause))
|
||
}
|
||
|
||
return result.String()
|
||
}
|
||
|
||
// GetErrorDetails 返回错误的详细信息,包括类型、消息、HTTP状态码和请求ID
|
||
func GetErrorDetails(err error) (errType string, message string, code int, requestID string) {
|
||
if err == nil {
|
||
return "", "", 0, ""
|
||
}
|
||
|
||
var appErr *AppError
|
||
if stderrors.As(err, &appErr) {
|
||
return appErr.Type, appErr.Message, appErr.Code, appErr.RequestID
|
||
}
|
||
|
||
return "unknown", err.Error(), 500, ""
|
||
}
|