package main import ( "errors" "fmt" ) // AppError 全局通用自定义错误 type AppError struct { Code int // 业务错误码 Msg string // 错误描述 Module string // 所属模块 Status int // HTTP 状态码(可选扩展) Err error // 底层原始错误(支持错误链) } // Error 实现标准 error 接口 func (e *AppError) Error() string { return fmt.Sprintf("[%s] 错误码:%d | HTTP:%d | 描述:%s", e.Module, e.Code, e.Status, e.Msg) } // Unwrap 返回底层错误,支持 errors.Unwrap 和 errors.As 递归解包 func (e *AppError) Unwrap() error { return e.Err } // 模拟数据库操作错误 func dbOperation(id string) error { if id == "not_found" { return fmt.Errorf("record [%s] not found: %w", id, errors.New("database empty")) } return nil } // 模拟业务逻辑 func businessDemo(name string) error { if name == "invalid" { return &AppError{ Code: 40010, Msg: "参数非法", Module: "user", Status: 400, } } if name == "db_error" { dbErr := dbOperation("not_found") return &AppError{ Code: 50001, Msg: "数据库操作失败", Module: "database", Status: 500, Err: dbErr, // 包装底层错误 } } return nil } // 统一错误处理 func parseError(err error) { var appErr *AppError // 断言自定义错误 if errors.As(err, &appErr) { fmt.Printf("捕获业务错误:%+v\n", appErr) // 如果有底层错误,继续解包 if appErr.Unwrap() != nil { fmt.Printf("底层错误:%v\n", appErr.Unwrap()) // 使用 errors.Is 检测底层错误 if errors.Is(appErr.Unwrap(), errors.New("database empty")) { fmt.Println("判定:底层是数据库空错误") } } return } // 处理通用错误 if err != nil { fmt.Printf("捕获系统错误:%v\n", err) } } func main() { fmt.Println("===== 自定义错误类型 =====") err := businessDemo("invalid") parseError(err) fmt.Println("\n===== 带错误链的自定义错误 =====") err2 := businessDemo("db_error") parseError(err2) fmt.Println("\n===== 使用 errors.As 深度提取 =====") var appErr *AppError if errors.As(err2, &appErr) { fmt.Printf("提取到 AppError - 模块:%s, 错误码:%d\n", appErr.Module, appErr.Code) } }