Skip to content

Go错误处理策略 - Golang企业级错误管理最佳实践

错误处理是Go语言的核心特性之一,良好的错误处理策略能够提高系统的健壮性、可维护性和用户体验。在企业级应用中,需要建立完善的错误管理体系。

📋 重点面试题

面试题 1:Go应用的企业级错误处理体系设计

难度级别:⭐⭐⭐⭐⭐
考察范围:错误处理/系统设计
技术标签error handling system reliability error management fault tolerance

详细解答

1. 错误处理体系架构

点击查看完整代码实现
点击查看完整代码实现
go
package main

import (
    "context"
    "fmt"
    "log"
    "runtime"
    "strconv"
    "strings"
    "sync"
    "time"
)

func demonstrateErrorHandlingStrategy() {
    fmt.Println("=== Go错误处理策略 ===")
    
    /*
    错误处理策略核心要素:
    
    1. 错误分类体系:
       - 业务错误:用户输入错误、权限错误等
       - 系统错误:网络错误、数据库错误等
       - 致命错误:内存不足、配置错误等
       - 临时错误:超时、限流等可重试错误
    
    2. 错误信息设计:
       - 错误码:唯一标识错误类型
       - 错误消息:用户友好的描述
       - 技术细节:开发者需要的详细信息
       - 上下文信息:请求ID、用户ID等
    
    3. 错误处理策略:
       - 快速失败:立即返回错误
       - 重试机制:自动重试临时错误
       - 降级处理:提供替代方案
       - 熔断保护:防止错误传播
    
    4. 错误监控告警:
       - 错误统计:错误率、错误分布
       - 异常检测:异常模式识别
       - 告警机制:及时通知相关人员
       - 错误追踪:完整的错误链路
    */
    
    demonstrateErrorClassification()
    demonstrateCustomErrors()
    demonstrateErrorPropagation()
    demonstrateErrorRecovery()
}

func demonstrateErrorClassification() {
    fmt.Println("\n--- 错误分类体系 ---")
    
    /*
    错误分类要点:
    
    1. 按错误性质分类:业务、系统、配置
    2. 按严重程度分类:致命、错误、警告
    3. 按处理方式分类:可重试、不可重试
    4. 按影响范围分类:用户级、服务级、系统级
    */
    
    // 错误类型定义
    type ErrorType int
    
    const (
        ErrorTypeBusiness ErrorType = iota // 业务错误
        ErrorTypeSystem                    // 系统错误
        ErrorTypeNetwork                   // 网络错误
        ErrorTypeValidation                // 验证错误
        ErrorTypePermission                // 权限错误
        ErrorTypeConfiguration             // 配置错误
        ErrorTypeTimeout                   // 超时错误
        ErrorTypeResource                  // 资源错误
    )
    
    func (et ErrorType) String() string {
        switch et {
        case ErrorTypeBusiness:
            return "BUSINESS"
        case ErrorTypeSystem:
            return "SYSTEM"
        case ErrorTypeNetwork:
            return "NETWORK"
        case ErrorTypeValidation:
            return "VALIDATION"
        case ErrorTypePermission:
            return "PERMISSION"
        case ErrorTypeConfiguration:
            return "CONFIGURATION"
        case ErrorTypeTimeout:
            return "TIMEOUT"
        case ErrorTypeResource:
            return "RESOURCE"
        default:
            return "UNKNOWN"
        }
    }
    
    // 错误严重级别
    type ErrorSeverity int
    
    const (
        SeverityLow ErrorSeverity = iota
        SeverityMedium
        SeverityHigh
        SeverityCritical
    )
    
    func (es ErrorSeverity) String() string {
        switch es {
        case SeverityLow:
            return "LOW"
        case SeverityMedium:
            return "MEDIUM"
        case SeverityHigh:
            return "HIGH"
        case SeverityCritical:
            return "CRITICAL"
        default:
            return "UNKNOWN"
        }
    }
    
    // 分类错误接口
    type ClassifiedError interface {
        error
        Code() string
        Type() ErrorType
        Severity() ErrorSeverity
        IsRetryable() bool
        IsTemporary() bool
        Details() map[string]interface{}
        StackTrace() string
    }
    
    // 基础分类错误实现
    type BaseClassifiedError struct {
        code       string
        message    string
        errorType  ErrorType
        severity   ErrorSeverity
        retryable  bool
        temporary  bool
        details    map[string]interface{}
        stackTrace string
        cause      error
    }
    
    func NewClassifiedError(code, message string, errorType ErrorType, severity ErrorSeverity) *BaseClassifiedError {
        return &BaseClassifiedError{
            code:       code,
            message:    message,
            errorType:  errorType,
            severity:   severity,
            retryable:  false,
            temporary:  false,
            details:    make(map[string]interface{}),
            stackTrace: captureStackTrace(),
        }
    }
    
    func (bce *BaseClassifiedError) Error() string {
        return fmt.Sprintf("[%s] %s: %s", bce.code, bce.errorType.String(), bce.message)
    }
    
    func (bce *BaseClassifiedError) Code() string {
        return bce.code
    }
    
    func (bce *BaseClassifiedError) Type() ErrorType {
        return bce.errorType
    }
    
    func (bce *BaseClassifiedError) Severity() ErrorSeverity {
        return bce.severity
    }
    
    func (bce *BaseClassifiedError) IsRetryable() bool {
        return bce.retryable
    }
    
    func (bce *BaseClassifiedError) IsTemporary() bool {
        return bce.temporary
    }
    
    func (bce *BaseClassifiedError) Details() map[string]interface{} {
        return bce.details
    }
    
    func (bce *BaseClassifiedError) StackTrace() string {
        return bce.stackTrace
    }
    
    func (bce *BaseClassifiedError) WithCause(cause error) *BaseClassifiedError {
        bce.cause = cause
        return bce
    }
    
    func (bce *BaseClassifiedError) WithDetail(key string, value interface{}) *BaseClassifiedError {
        bce.details[key] = value
        return bce
    }
    
    func (bce *BaseClassifiedError) SetRetryable(retryable bool) *BaseClassifiedError {
        bce.retryable = retryable
        return bce
    }
    
    func (bce *BaseClassifiedError) SetTemporary(temporary bool) *BaseClassifiedError {
        bce.temporary = temporary
        return bce
    }
    
    func captureStackTrace() string {
        var buf strings.Builder
        for i := 2; i < 10; i++ { // 跳过当前函数和调用者
            pc, file, line, ok := runtime.Caller(i)
            if !ok {
                break
            }
            
            fn := runtime.FuncForPC(pc)
            if fn == nil {
                continue
            }
            
            funcName := fn.Name()
            if idx := strings.LastIndex(funcName, "/"); idx != -1 {
                funcName = funcName[idx+1:]
            }
            
            if idx := strings.LastIndex(file, "/"); idx != -1 {
                file = file[idx+1:]
            }
            
            buf.WriteString(fmt.Sprintf("  %s:%d %s\n", file, line, funcName))
        }
        return buf.String()
    }
    
    // 具体错误类型工厂
    type ErrorFactory struct{}
    
    func (ef *ErrorFactory) NewValidationError(message string) *BaseClassifiedError {
        return NewClassifiedError("VALIDATION_001", message, ErrorTypeValidation, SeverityMedium)
    }
    
    func (ef *ErrorFactory) NewPermissionError(message string) *BaseClassifiedError {
        return NewClassifiedError("PERMISSION_001", message, ErrorTypePermission, SeverityHigh)
    }
    
    func (ef *ErrorFactory) NewNetworkError(message string) *BaseClassifiedError {
        return NewClassifiedError("NETWORK_001", message, ErrorTypeNetwork, SeverityMedium).
            SetRetryable(true).
            SetTemporary(true)
    }
    
    func (ef *ErrorFactory) NewDatabaseError(message string) *BaseClassifiedError {
        return NewClassifiedError("DATABASE_001", message, ErrorTypeSystem, SeverityHigh).
            SetRetryable(true)
    }
    
    func (ef *ErrorFactory) NewTimeoutError(message string) *BaseClassifiedError {
        return NewClassifiedError("TIMEOUT_001", message, ErrorTypeTimeout, SeverityMedium).
            SetRetryable(true).
            SetTemporary(true)
    }
    
    func (ef *ErrorFactory) NewBusinessError(code, message string) *BaseClassifiedError {
        return NewClassifiedError(code, message, ErrorTypeBusiness, SeverityLow)
    }
    
    // 演示错误分类
    fmt.Printf("错误分类体系演示:\n")
    
    factory := &ErrorFactory{}
    
    // 创建不同类型的错误
    errors := []ClassifiedError{
        factory.NewValidationError("用户名不能为空"),
        factory.NewPermissionError("权限不足,无法访问该资源"),
        factory.NewNetworkError("网络连接超时").WithDetail("timeout", "5s"),
        factory.NewDatabaseError("数据库连接失败").WithDetail("host", "localhost:5432"),
        factory.NewTimeoutError("请求处理超时").WithDetail("duration", "30s"),
        factory.NewBusinessError("ORDER_001", "订单状态不允许取消"),
    }
    
    fmt.Printf("  📊 错误分类统计:\n")
    
    typeCount := make(map[ErrorType]int)
    severityCount := make(map[ErrorSeverity]int)
    retryableCount := 0
    temporaryCount := 0
    
    for i, err := range errors {
        fmt.Printf("    %d. %s\n", i+1, err.Error())
        fmt.Printf("       类型: %s, 严重程度: %s\n", err.Type().String(), err.Severity().String())
        fmt.Printf("       可重试: %t, 临时性: %t\n", err.IsRetryable(), err.IsTemporary())
        
        if len(err.Details()) > 0 {
            fmt.Printf("       详细信息: %v\n", err.Details())
        }
        
        // 统计
        typeCount[err.Type()]++
        severityCount[err.Severity()]++
        if err.IsRetryable() {
            retryableCount++
        }
        if err.IsTemporary() {
            temporaryCount++
        }
        
        fmt.Println()
    }
    
    fmt.Printf("  📈 统计摘要:\n")
    fmt.Printf("    按类型分布:\n")
    for errorType, count := range typeCount {
        fmt.Printf("      %s: %d\n", errorType.String(), count)
    }
    
    fmt.Printf("    按严重程度分布:\n")
    for severity, count := range severityCount {
        fmt.Printf("      %s: %d\n", severity.String(), count)
    }
    
    fmt.Printf("    可重试错误: %d/%d\n", retryableCount, len(errors))
    fmt.Printf("    临时性错误: %d/%d\n", temporaryCount, len(errors))
}

func demonstrateCustomErrors() {
    fmt.Println("\n--- 自定义错误设计 ---")
    
    /*
    自定义错误要点:
    
    1. 错误包装:保留原始错误信息
    2. 上下文传递:携带请求上下文
    3. 错误链:构建错误调用链
    4. 元数据:附加诊断信息
    */
    
    // 上下文错误
    type ContextualError struct {
        BaseError     error
        Context       context.Context
        RequestID     string
        UserID        string
        Operation     string
        Timestamp     time.Time
        AdditionalInfo map[string]interface{}
    }
    
    func NewContextualError(ctx context.Context, operation string, baseError error) *ContextualError {
        ce := &ContextualError{
            BaseError:      baseError,
            Context:        ctx,
            Operation:      operation,
            Timestamp:      time.Now(),
            AdditionalInfo: make(map[string]interface{}),
        }
        
        // 从上下文中提取信息
        if requestID := ctx.Value("request_id"); requestID != nil {
            if id, ok := requestID.(string); ok {
                ce.RequestID = id
            }
        }
        
        if userID := ctx.Value("user_id"); userID != nil {
            if id, ok := userID.(string); ok {
                ce.UserID = id
            }
        }
        
        return ce
    }
    
    func (ce *ContextualError) Error() string {
        return fmt.Sprintf("[%s] %s: %v", ce.Operation, ce.RequestID, ce.BaseError)
    }
    
    func (ce *ContextualError) Unwrap() error {
        return ce.BaseError
    }
    
    func (ce *ContextualError) WithInfo(key string, value interface{}) *ContextualError {
        ce.AdditionalInfo[key] = value
        return ce
    }
    
    // 错误链构建器
    type ErrorChain struct {
        errors []error
        mutex  sync.RWMutex
    }
    
    func NewErrorChain() *ErrorChain {
        return &ErrorChain{
            errors: make([]error, 0),
        }
    }
    
    func (ec *ErrorChain) Add(err error) *ErrorChain {
        if err == nil {
            return ec
        }
        
        ec.mutex.Lock()
        defer ec.mutex.Unlock()
        ec.errors = append(ec.errors, err)
        return ec
    }
    
    func (ec *ErrorChain) HasErrors() bool {
        ec.mutex.RLock()
        defer ec.mutex.RUnlock()
        return len(ec.errors) > 0
    }
    
    func (ec *ErrorChain) Error() string {
        ec.mutex.RLock()
        defer ec.mutex.RUnlock()
        
        if len(ec.errors) == 0 {
            return "no errors"
        }
        
        if len(ec.errors) == 1 {
            return ec.errors[0].Error()
        }
        
        var builder strings.Builder
        builder.WriteString("multiple errors occurred:\n")
        for i, err := range ec.errors {
            builder.WriteString(fmt.Sprintf("  %d. %s\n", i+1, err.Error()))
        }
        
        return builder.String()
    }
    
    func (ec *ErrorChain) Errors() []error {
        ec.mutex.RLock()
        defer ec.mutex.RUnlock()
        
        result := make([]error, len(ec.errors))
        copy(result, ec.errors)
        return result
    }
    
    func (ec *ErrorChain) First() error {
        ec.mutex.RLock()
        defer ec.mutex.RUnlock()
        
        if len(ec.errors) > 0 {
            return ec.errors[0]
        }
        return nil
    }
    
    func (ec *ErrorChain) Last() error {
        ec.mutex.RLock()
        defer ec.mutex.RUnlock()
        
        if len(ec.errors) > 0 {
            return ec.errors[len(ec.errors)-1]
        }
        return nil
    }
    
    // 业务错误包装器
    type BusinessErrorWrapper struct {
        UserMessage    string // 用户友好的消息
        TechnicalError error  // 技术错误详情
        ErrorCode      string // 业务错误码
        Suggestions    []string // 解决建议
    }
    
    func NewBusinessErrorWrapper(code, userMessage string, technicalError error) *BusinessErrorWrapper {
        return &BusinessErrorWrapper{
            UserMessage:    userMessage,
            TechnicalError: technicalError,
            ErrorCode:      code,
            Suggestions:    make([]string, 0),
        }
    }
    
    func (bew *BusinessErrorWrapper) Error() string {
        return fmt.Sprintf("[%s] %s", bew.ErrorCode, bew.UserMessage)
    }
    
    func (bew *BusinessErrorWrapper) Unwrap() error {
        return bew.TechnicalError
    }
    
    func (bew *BusinessErrorWrapper) AddSuggestion(suggestion string) *BusinessErrorWrapper {
        bew.Suggestions = append(bew.Suggestions, suggestion)
        return bew
    }
    
    func (bew *BusinessErrorWrapper) GetUserMessage() string {
        return bew.UserMessage
    }
    
    func (bew *BusinessErrorWrapper) GetTechnicalDetails() string {
        if bew.TechnicalError != nil {
            return bew.TechnicalError.Error()
        }
        return ""
    }
    
    func (bew *BusinessErrorWrapper) GetSuggestions() []string {
        return bew.Suggestions
    }
    
    // 演示自定义错误
    fmt.Printf("自定义错误设计演示:\n")
    
    // 模拟业务操作
    simulateBusinessOperation := func() error {
        // 创建带上下文的请求
        ctx := context.Background()
        ctx = context.WithValue(ctx, "request_id", "req-12345")
        ctx = context.WithValue(ctx, "user_id", "user-67890")
        
        // 模拟数据库错误
        dbError := fmt.Errorf("connection timeout after 5s")
        
        // 包装为上下文错误
        contextError := NewContextualError(ctx, "user_lookup", dbError).
            WithInfo("table", "users").
            WithInfo("query_duration", "5.2s")
        
        // 包装为业务错误
        businessError := NewBusinessErrorWrapper(
            "USER_LOOKUP_FAILED",
            "用户信息获取失败,请稍后重试",
            contextError,
        ).AddSuggestion("检查网络连接").
            AddSuggestion("联系技术支持")
        
        return businessError
    }
    
    // 模拟多个错误的聚合
    simulateMultipleErrors := func() error {
        chain := NewErrorChain()
        
        // 模拟验证错误
        chain.Add(fmt.Errorf("用户名不能为空"))
        chain.Add(fmt.Errorf("密码长度不足8位"))
        chain.Add(fmt.Errorf("邮箱格式不正确"))
        
        if chain.HasErrors() {
            return chain
        }
        return nil
    }
    
    fmt.Printf("  🔍 上下文错误示例:\n")
    if err := simulateBusinessOperation(); err != nil {
        fmt.Printf("    错误: %s\n", err.Error())
        
        // 类型断言获取详细信息
        if businessErr, ok := err.(*BusinessErrorWrapper); ok {
            fmt.Printf("    用户消息: %s\n", businessErr.GetUserMessage())
            fmt.Printf("    技术详情: %s\n", businessErr.GetTechnicalDetails())
            fmt.Printf("    解决建议: %v\n", businessErr.GetSuggestions())
            
            // 解包获取原始错误
            if contextErr, ok := businessErr.Unwrap().(*ContextualError); ok {
                fmt.Printf("    请求ID: %s\n", contextErr.RequestID)
                fmt.Printf("    用户ID: %s\n", contextErr.UserID)
                fmt.Printf("    操作: %s\n", contextErr.Operation)
                fmt.Printf("    时间戳: %s\n", contextErr.Timestamp.Format(time.RFC3339))
                fmt.Printf("    附加信息: %v\n", contextErr.AdditionalInfo)
            }
        }
    }
    
    fmt.Printf("\n  📝 错误链示例:\n")
    if err := simulateMultipleErrors(); err != nil {
        fmt.Printf("    %s", err.Error())
        
        if errorChain, ok := err.(*ErrorChain); ok {
            fmt.Printf("    错误总数: %d\n", len(errorChain.Errors()))
            fmt.Printf("    首个错误: %s\n", errorChain.First().Error())
            fmt.Printf("    最后错误: %s\n", errorChain.Last().Error())
        }
    }
}

func demonstrateErrorPropagation() {
    fmt.Println("\n--- 错误传播机制 ---")
    
    /*
    错误传播要点:
    
    1. 错误包装:保留调用栈信息
    2. 错误转换:适配不同层级的错误
    3. 错误过滤:决定哪些错误需要传播
    4. 错误增强:添加上下文信息
    */
    
    // 错误传播器
    type ErrorPropagator struct {
        filters []ErrorFilter
        transformers []ErrorTransformer
        enhancers []ErrorEnhancer
    }
    
    type ErrorFilter interface {
        ShouldPropagate(err error) bool
    }
    
    type ErrorTransformer interface {
        Transform(err error) error
    }
    
    type ErrorEnhancer interface {
        Enhance(err error, context map[string]interface{}) error
    }
    
    // 严重性过滤器
    type SeverityFilter struct {
        MinSeverity ErrorSeverity
    }
    
    func (sf *SeverityFilter) ShouldPropagate(err error) bool {
        if classifiedErr, ok := err.(ClassifiedError); ok {
            return classifiedErr.Severity() >= sf.MinSeverity
        }
        return true // 未分类错误默认传播
    }
    
    // 错误类型转换器
    type ErrorTypeTransformer struct {
        FromType ErrorType
        ToType   ErrorType
    }
    
    func (ett *ErrorTypeTransformer) Transform(err error) error {
        if classifiedErr, ok := err.(*BaseClassifiedError); ok {
            if classifiedErr.Type() == ett.FromType {
                // 创建新的错误类型
                newErr := NewClassifiedError(
                    classifiedErr.Code(),
                    classifiedErr.message,
                    ett.ToType,
                    classifiedErr.Severity(),
                )
                newErr.details = classifiedErr.details
                return newErr
            }
        }
        return err
    }
    
    // 上下文增强器
    type ContextEnhancer struct {
        Service string
        Version string
    }
    
    func (ce *ContextEnhancer) Enhance(err error, context map[string]interface{}) error {
        // 创建增强的错误包装
        enhanced := &EnhancedError{
            OriginalError: err,
            Service:       ce.Service,
            Version:       ce.Version,
            Context:       context,
            Timestamp:     time.Now(),
        }
        return enhanced
    }
    
    type EnhancedError struct {
        OriginalError error
        Service       string
        Version       string
        Context       map[string]interface{}
        Timestamp     time.Time
    }
    
    func (ee *EnhancedError) Error() string {
        return fmt.Sprintf("[%s@%s] %s", ee.Service, ee.Version, ee.OriginalError.Error())
    }
    
    func (ee *EnhancedError) Unwrap() error {
        return ee.OriginalError
    }
    
    func NewErrorPropagator() *ErrorPropagator {
        return &ErrorPropagator{
            filters:      make([]ErrorFilter, 0),
            transformers: make([]ErrorTransformer, 0),
            enhancers:    make([]ErrorEnhancer, 0),
        }
    }
    
    func (ep *ErrorPropagator) AddFilter(filter ErrorFilter) {
        ep.filters = append(ep.filters, filter)
    }
    
    func (ep *ErrorPropagator) AddTransformer(transformer ErrorTransformer) {
        ep.transformers = append(ep.transformers, transformer)
    }
    
    func (ep *ErrorPropagator) AddEnhancer(enhancer ErrorEnhancer) {
        ep.enhancers = append(ep.enhancers, enhancer)
    }
    
    func (ep *ErrorPropagator) Propagate(err error, context map[string]interface{}) error {
        if err == nil {
            return nil
        }
        
        // 应用过滤器
        for _, filter := range ep.filters {
            if !filter.ShouldPropagate(err) {
                return nil // 不传播此错误
            }
        }
        
        // 应用转换器
        for _, transformer := range ep.transformers {
            err = transformer.Transform(err)
        }
        
        // 应用增强器
        for _, enhancer := range ep.enhancers {
            err = enhancer.Enhance(err, context)
        }
        
        return err
    }
    
    // 演示错误传播
    fmt.Printf("错误传播机制演示:\n")
    
    // 创建错误传播器
    propagator := NewErrorPropagator()
    
    // 添加严重性过滤器(只传播中等以上严重度的错误)
    propagator.AddFilter(&SeverityFilter{MinSeverity: SeverityMedium})
    
    // 添加错误类型转换器(将网络错误转换为系统错误)
    propagator.AddTransformer(&ErrorTypeTransformer{
        FromType: ErrorTypeNetwork,
        ToType:   ErrorTypeSystem,
    })
    
    // 添加上下文增强器
    propagator.AddEnhancer(&ContextEnhancer{
        Service: "user-service",
        Version: "v1.2.3",
    })
    
    // 测试不同类型的错误传播
    factory := &ErrorFactory{}
    testErrors := []error{
        factory.NewValidationError("输入验证失败"),                    // 中等严重度,应该传播
        NewClassifiedError("TRACE_001", "调试信息", ErrorTypeBusiness, SeverityLow), // 低严重度,应该被过滤
        factory.NewNetworkError("网络连接失败"),                      // 网络错误,应该被转换为系统错误
        factory.NewDatabaseError("数据库查询失败"),                    // 高严重度,应该传播
    }
    
    context := map[string]interface{}{
        "request_id": "req-98765",
        "user_id":    "user-12345",
        "operation":  "get_user_profile",
    }
    
    fmt.Printf("  🚀 错误传播测试:\n")
    for i, originalErr := range testErrors {
        fmt.Printf("    测试 %d - 原始错误: %s\n", i+1, originalErr.Error())
        
        propagatedErr := propagator.Propagate(originalErr, context)
        
        if propagatedErr == nil {
            fmt.Printf("      结果: 错误被过滤,未传播\n")
        } else {
            fmt.Printf("      结果: %s\n", propagatedErr.Error())
            
            // 检查是否被增强
            if enhanced, ok := propagatedErr.(*EnhancedError); ok {
                fmt.Printf("      服务: %s\n", enhanced.Service)
                fmt.Printf("      版本: %s\n", enhanced.Version)
                fmt.Printf("      时间戳: %s\n", enhanced.Timestamp.Format("15:04:05"))
                fmt.Printf("      上下文: %v\n", enhanced.Context)
            }
        }
        fmt.Println()
    }
}

func demonstrateErrorRecovery() {
    fmt.Println("\n--- 错误恢复策略 ---")
    
    /*
    错误恢复要点:
    
    1. 重试机制:指数退避、最大重试次数
    2. 熔断保护:防止级联失败
    3. 降级处理:提供备用方案
    4. 超时控制:避免无限等待
    */
    
    // 重试策略
    type RetryStrategy interface {
        ShouldRetry(attempt int, err error) bool
        NextDelay(attempt int) time.Duration
        MaxAttempts() int
    }
    
    // 指数退避重试策略
    type ExponentialBackoffStrategy struct {
        InitialDelay time.Duration
        MaxDelay     time.Duration
        Multiplier   float64
        MaxRetries   int
    }
    
    func (ebs *ExponentialBackoffStrategy) ShouldRetry(attempt int, err error) bool {
        if attempt >= ebs.MaxRetries {
            return false
        }
        
        // 检查错误是否可重试
        if classifiedErr, ok := err.(ClassifiedError); ok {
            return classifiedErr.IsRetryable()
        }
        
        return false
    }
    
    func (ebs *ExponentialBackoffStrategy) NextDelay(attempt int) time.Duration {
        delay := time.Duration(float64(ebs.InitialDelay) * 
            pow(ebs.Multiplier, float64(attempt)))
        
        if delay > ebs.MaxDelay {
            delay = ebs.MaxDelay
        }
        
        return delay
    }
    
    func (ebs *ExponentialBackoffStrategy) MaxAttempts() int {
        return ebs.MaxRetries
    }
    
    // 简单的幂运算实现
    func pow(base, exp float64) float64 {
        if exp == 0 {
            return 1
        }
        result := base
        for i := 1; i < int(exp); i++ {
            result *= base
        }
        return result
    }
    
    // 重试执行器
    type RetryExecutor struct {
        strategy RetryStrategy
        logger   *log.Logger
    }
    
    func NewRetryExecutor(strategy RetryStrategy) *RetryExecutor {
        return &RetryExecutor{
            strategy: strategy,
            logger:   log.New(log.Writer(), "[RETRY] ", log.LstdFlags),
        }
    }
    
    func (re *RetryExecutor) Execute(ctx context.Context, operation func() error) error {
        var lastErr error
        
        for attempt := 0; attempt < re.strategy.MaxAttempts(); attempt++ {
            // 检查上下文是否已取消
            select {
            case <-ctx.Done():
                return ctx.Err()
            default:
            }
            
            // 执行操作
            err := operation()
            if err == nil {
                if attempt > 0 {
                    re.logger.Printf("操作在第 %d 次重试后成功", attempt+1)
                }
                return nil
            }
            
            lastErr = err
            
            // 检查是否应该重试
            if !re.strategy.ShouldRetry(attempt, err) {
                re.logger.Printf("错误不可重试或达到最大重试次数: %v", err)
                break
            }
            
            // 计算延迟时间
            delay := re.strategy.NextDelay(attempt)
            re.logger.Printf("第 %d 次重试失败: %v, %v 后重试", attempt+1, err, delay)
            
            // 等待重试
            select {
            case <-ctx.Done():
                return ctx.Err()
            case <-time.After(delay):
                // 继续重试
            }
        }
        
        return fmt.Errorf("重试 %d 次后仍然失败: %v", re.strategy.MaxAttempts(), lastErr)
    }
    
    // 熔断器(简化版)
    type CircuitBreaker struct {
        name          string
        maxFailures   int
        resetTimeout  time.Duration
        failures      int
        lastFailTime  time.Time
        state         string
        mutex         sync.RWMutex
    }
    
    func NewCircuitBreaker(name string, maxFailures int, resetTimeout time.Duration) *CircuitBreaker {
        return &CircuitBreaker{
            name:         name,
            maxFailures:  maxFailures,
            resetTimeout: resetTimeout,
            state:        "CLOSED",
        }
    }
    
    func (cb *CircuitBreaker) Execute(operation func() error) error {
        cb.mutex.RLock()
        state := cb.state
        failures := cb.failures
        lastFailTime := cb.lastFailTime
        cb.mutex.RUnlock()
        
        // 检查熔断器状态
        if state == "OPEN" {
            if time.Since(lastFailTime) > cb.resetTimeout {
                cb.mutex.Lock()
                cb.state = "HALF_OPEN"
                cb.mutex.Unlock()
            } else {
                return fmt.Errorf("熔断器 %s 已开启", cb.name)
            }
        }
        
        // 执行操作
        err := operation()
        
        cb.mutex.Lock()
        defer cb.mutex.Unlock()
        
        if err != nil {
            cb.failures++
            cb.lastFailTime = time.Now()
            
            if cb.failures >= cb.maxFailures {
                cb.state = "OPEN"
                log.Printf("熔断器 %s 开启,失败次数: %d", cb.name, cb.failures)
            }
            
            return err
        }
        
        // 成功时重置
        if cb.state == "HALF_OPEN" {
            cb.state = "CLOSED"
            log.Printf("熔断器 %s 恢复正常", cb.name)
        }
        cb.failures = 0
        
        return nil
    }
    
    // 降级处理器
    type FallbackHandler struct {
        primary   func() (interface{}, error)
        fallback  func() (interface{}, error)
        threshold time.Duration
    }
    
    func NewFallbackHandler(primary, fallback func() (interface{}, error), threshold time.Duration) *FallbackHandler {
        return &FallbackHandler{
            primary:   primary,
            fallback:  fallback,
            threshold: threshold,
        }
    }
    
    func (fh *FallbackHandler) Execute() (interface{}, error) {
        // 设置超时
        ctx, cancel := context.WithTimeout(context.Background(), fh.threshold)
        defer cancel()
        
        resultCh := make(chan interface{}, 1)
        errorCh := make(chan error, 1)
        
        // 执行主要操作
        go func() {
            result, err := fh.primary()
            if err != nil {
                errorCh <- err
            } else {
                resultCh <- result
            }
        }()
        
        select {
        case result := <-resultCh:
            return result, nil
        case err := <-errorCh:
            log.Printf("主要操作失败,执行降级: %v", err)
            return fh.fallback()
        case <-ctx.Done():
            log.Printf("主要操作超时,执行降级")
            return fh.fallback()
        }
    }
    
    // 演示错误恢复
    fmt.Printf("错误恢复策略演示:\n")
    
    // 1. 重试机制演示
    fmt.Printf("  🔄 重试机制测试:\n")
    
    retryStrategy := &ExponentialBackoffStrategy{
        InitialDelay: 100 * time.Millisecond,
        MaxDelay:     1 * time.Second,
        Multiplier:   2.0,
        MaxRetries:   3,
    }
    
    executor := NewRetryExecutor(retryStrategy)
    
    // 模拟不稳定的操作
    callCount := 0
    unstableOperation := func() error {
        callCount++
        if callCount < 3 { // 前两次失败
            factory := &ErrorFactory{}
            return factory.NewNetworkError(fmt.Sprintf("网络错误 #%d", callCount))
        }
        return nil // 第三次成功
    }
    
    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()
    
    if err := executor.Execute(ctx, unstableOperation); err != nil {
        fmt.Printf("    ❌ 重试失败: %v\n", err)
    } else {
        fmt.Printf("    ✅ 重试成功,总调用次数: %d\n", callCount)
    }
    
    // 2. 熔断器演示
    fmt.Printf("\n  ⚡ 熔断器测试:\n")
    
    breaker := NewCircuitBreaker("test-service", 2, 2*time.Second)
    
    // 模拟失败操作
    failingOperation := func() error {
        return fmt.Errorf("服务不可用")
    }
    
    // 连续失败触发熔断
    for i := 1; i <= 5; i++ {
        err := breaker.Execute(failingOperation)
        if err != nil {
            fmt.Printf("    调用 %d: ❌ %v\n", i, err)
        }
    }
    
    // 3. 降级处理演示
    fmt.Printf("\n  📉 降级处理测试:\n")
    
    // 主要服务(模拟慢响应)
    primaryService := func() (interface{}, error) {
        time.Sleep(200 * time.Millisecond) // 模拟慢响应
        return "来自主要服务的数据", nil
    }
    
    // 降级服务(快速响应)
    fallbackService := func() (interface{}, error) {
        return "来自缓存的数据", nil
    }
    
    handler := NewFallbackHandler(primaryService, fallbackService, 100*time.Millisecond)
    
    result, err := handler.Execute()
    if err != nil {
        fmt.Printf("    ❌ 降级处理失败: %v\n", err)
    } else {
        fmt.Printf("    ✅ 降级处理成功: %v\n", result)
    }
    
    fmt.Printf("\n  📋 错误恢复最佳实践:\n")
    fmt.Printf("    1. 识别可重试的错误类型\n")
    fmt.Printf("    2. 实现指数退避重试策略\n")
    fmt.Printf("    3. 使用熔断器防止级联失败\n")
    fmt.Printf("    4. 提供降级和备用方案\n")
    fmt.Printf("    5. 设置合理的超时时间\n")
    fmt.Printf("    6. 监控错误率和恢复情况\n")
}

func main() {
    demonstrateErrorHandlingStrategy()
}

:::

🎯 核心知识点总结

错误分类体系要点

  1. 按性质分类: 业务错误、系统错误、网络错误等
  2. 按严重程度: 低、中、高、严重四个级别
  3. 按处理方式: 可重试、不可重试、临时性错误
  4. 标准化信息: 错误码、消息、上下文、堆栈信息

自定义错误要点

  1. 错误包装: 保留原始错误同时添加上下文信息
  2. 错误链: 构建多个错误的聚合和链式传播
  3. 业务包装: 区分用户友好消息和技术详情
  4. 元数据携带: 附加诊断和调试信息

错误传播要点

  1. 过滤机制: 根据严重程度决定是否传播错误
  2. 错误转换: 适配不同层级的错误类型
  3. 上下文增强: 添加服务、版本、时间戳等信息
  4. 链路追踪: 保持错误在调用链中的完整传播

错误恢复要点

  1. 重试策略: 指数退避、最大重试次数、可重试错误判断
  2. 熔断保护: 防止故障扩散和级联失败
  3. 降级处理: 提供备用方案和缓存数据
  4. 超时控制: 避免无限等待和资源占用

🔍 面试准备建议

  1. 理解原理: 深入理解Go错误处理的设计思想和最佳实践
  2. 设计能力: 掌握企业级错误处理体系的设计方法
  3. 实践经验: 积累不同场景下的错误处理实际经验
  4. 工具使用: 熟悉错误监控、追踪和分析工具
  5. 系统思维: 从系统可靠性角度思考错误处理策略

正在精进