feat: 优化 AppError 结构,确保链式调用方法线程安全并返回新实例;更新开发规则,增强对分页和错误处理的要求

This commit is contained in:
2025-12-29 14:50:24 +08:00
parent 7848dc2853
commit 32b75d7428
2 changed files with 73 additions and 35 deletions

View File

@@ -1,65 +1,93 @@
package errorx
import (
"fmt"
"runtime"
"fmt"
"runtime"
)
// AppError 应用错误结构
type AppError struct {
Code ErrorCode `json:"code"`
Message string `json:"message"`
StatusCode int `json:"-"`
Data any `json:"data,omitempty"`
ID string `json:"id,omitempty"`
Code ErrorCode `json:"code"`
Message string `json:"message"`
StatusCode int `json:"-"`
Data any `json:"data,omitempty"`
ID string `json:"id,omitempty"`
//
originalErr error
file string
params []any
sql string
//
originalErr error
file string
params []any
sql string
}
// Error 实现 error 接口
func (e *AppError) Error() string {
return fmt.Sprintf("[%d] %s", e.Code, e.Message)
return fmt.Sprintf("[%d] %s", e.Code, e.Message)
}
// Unwrap 允许通过 errors.Unwrap 遍历到原始错误
func (e *AppError) Unwrap() error { return e.originalErr }
// copy 返回 AppError 的副本,用于链式调用时的并发安全
func (e *AppError) copy() *AppError {
newErr := *e
return &newErr
}
// WithCause 携带原始错误并记录调用栈
func (e *AppError) WithCause(err error) *AppError {
newErr := e.copy()
newErr.originalErr = err
//
if _, file, line, ok := runtime.Caller(1); ok {
newErr.file = fmt.Sprintf("%s:%d", file, line)
}
return newErr
}
// WithData 添加数据
func (e *AppError) WithData(data any) *AppError {
e.Data = data
return e
newErr := e.copy()
newErr.Data = data
return newErr
}
// WithMsg 设置消息
func (e *AppError) WithMsg(msg string) *AppError {
e.Message = msg
return e
newErr := e.copy()
newErr.Message = msg
return newErr
}
func (e *AppError) WithMsgf(format string, args ...any) *AppError {
newErr := e.copy()
newErr.Message = fmt.Sprintf(format, args...)
return newErr
}
// WithSQL 记录SQL信息
func (e *AppError) WithSQL(sql string) *AppError {
e.sql = sql
return e
newErr := e.copy()
newErr.sql = sql
return newErr
}
// WithParams 记录参数信息,并自动获取调用位置
func (e *AppError) WithParams(params ...any) *AppError {
e.params = params
if _, file, line, ok := runtime.Caller(1); ok {
e.file = fmt.Sprintf("%s:%d", file, line)
}
return e
newErr := e.copy()
newErr.params = params
if _, file, line, ok := runtime.Caller(1); ok {
newErr.file = fmt.Sprintf("%s:%d", file, line)
}
return newErr
}
// NewError 创建应用错误
func NewError(code ErrorCode, statusCode int, message string) *AppError {
return &AppError{
Code: code,
Message: message,
StatusCode: statusCode,
}
return &AppError{
Code: code,
Message: message,
StatusCode: statusCode,
}
}