Files
AUTO-MAS-test/Go_Updater/errors/errors.go
AoXuan 228e66315c feat(Go_Updater): 添加全新 Go 语言实现的自动更新器
- 新增多个源文件和目录,包括 app.rc、assets、build 脚本等
- 实现了与 MirrorChyan API 交互的客户端逻辑
- 添加了版本检查、更新检测和下载 URL 生成等功能
- 嵌入了配置模板和资源文件系统
- 提供了完整的构建和发布流程
2025-07-20 16:30:14 +08:00

219 lines
5.0 KiB
Go

package errors
import (
"fmt"
"time"
)
// ErrorType 定义错误类型枚举
type ErrorType int
const (
NetworkError ErrorType = iota
APIError
FileError
ConfigError
InstallError
)
// String 返回错误类型的字符串表示
func (et ErrorType) String() string {
switch et {
case NetworkError:
return "NetworkError"
case APIError:
return "APIError"
case FileError:
return "FileError"
case ConfigError:
return "ConfigError"
case InstallError:
return "InstallError"
default:
return "UnknownError"
}
}
// UpdaterError 统一的错误结构体
type UpdaterError struct {
Type ErrorType
Message string
Cause error
Timestamp time.Time
Context map[string]interface{}
}
// Error 实现error接口
func (ue *UpdaterError) Error() string {
if ue.Cause != nil {
return fmt.Sprintf("[%s] %s: %v", ue.Type, ue.Message, ue.Cause)
}
return fmt.Sprintf("[%s] %s", ue.Type, ue.Message)
}
// Unwrap 支持错误链
func (ue *UpdaterError) Unwrap() error {
return ue.Cause
}
// NewUpdaterError 创建新的UpdaterError
func NewUpdaterError(errorType ErrorType, message string, cause error) *UpdaterError {
return &UpdaterError{
Type: errorType,
Message: message,
Cause: cause,
Timestamp: time.Now(),
Context: make(map[string]interface{}),
}
}
// WithContext 添加上下文信息
func (ue *UpdaterError) WithContext(key string, value interface{}) *UpdaterError {
ue.Context[key] = value
return ue
}
// GetUserFriendlyMessage 获取用户友好的错误消息
func (ue *UpdaterError) GetUserFriendlyMessage() string {
switch ue.Type {
case NetworkError:
return "网络连接失败,请检查网络连接后重试"
case APIError:
return "服务器响应异常,请稍后重试或联系技术支持"
case FileError:
return "文件操作失败,请检查文件权限和磁盘空间"
case ConfigError:
return "配置文件错误,程序将使用默认配置"
case InstallError:
return "安装过程中出现错误,程序将尝试回滚更改"
default:
return "发生未知错误,请联系技术支持"
}
}
// RetryConfig 重试配置
type RetryConfig struct {
MaxRetries int
InitialDelay time.Duration
MaxDelay time.Duration
BackoffFactor float64
RetryableErrors []ErrorType
}
// DefaultRetryConfig 默认重试配置
func DefaultRetryConfig() *RetryConfig {
return &RetryConfig{
MaxRetries: 3,
InitialDelay: time.Second,
MaxDelay: 30 * time.Second,
BackoffFactor: 2.0,
RetryableErrors: []ErrorType{NetworkError, APIError},
}
}
// IsRetryable 检查错误是否可重试
func (rc *RetryConfig) IsRetryable(err error) bool {
if ue, ok := err.(*UpdaterError); ok {
for _, retryableType := range rc.RetryableErrors {
if ue.Type == retryableType {
return true
}
}
}
return false
}
// CalculateDelay 计算重试延迟时间
func (rc *RetryConfig) CalculateDelay(attempt int) time.Duration {
delay := time.Duration(float64(rc.InitialDelay) * pow(rc.BackoffFactor, float64(attempt)))
if delay > rc.MaxDelay {
delay = rc.MaxDelay
}
return delay
}
// pow 简单的幂运算实现
func pow(base, exp float64) float64 {
result := 1.0
for i := 0; i < int(exp); i++ {
result *= base
}
return result
}
// RetryableOperation 可重试的操作函数类型
type RetryableOperation func() error
// ExecuteWithRetry 执行带重试的操作
func ExecuteWithRetry(operation RetryableOperation, config *RetryConfig) error {
var lastErr error
for attempt := 0; attempt <= config.MaxRetries; attempt++ {
err := operation()
if err == nil {
return nil
}
lastErr = err
// 如果不是可重试的错误,直接返回
if !config.IsRetryable(err) {
return err
}
// 如果已经是最后一次尝试,不再等待
if attempt == config.MaxRetries {
break
}
// 计算延迟时间并等待
delay := config.CalculateDelay(attempt)
time.Sleep(delay)
}
return lastErr
}
// ErrorHandler 错误处理器接口
type ErrorHandler interface {
HandleError(err error) error
ShouldRetry(err error) bool
GetUserMessage(err error) string
}
// DefaultErrorHandler 默认错误处理器
type DefaultErrorHandler struct {
retryConfig *RetryConfig
}
// NewDefaultErrorHandler 创建默认错误处理器
func NewDefaultErrorHandler() *DefaultErrorHandler {
return &DefaultErrorHandler{
retryConfig: DefaultRetryConfig(),
}
}
// HandleError 处理错误
func (h *DefaultErrorHandler) HandleError(err error) error {
if ue, ok := err.(*UpdaterError); ok {
// 记录错误上下文
ue.WithContext("handled_at", time.Now())
return ue
}
// 将普通错误包装为UpdaterError
return NewUpdaterError(NetworkError, "未分类错误", err)
}
// ShouldRetry 判断是否应该重试
func (h *DefaultErrorHandler) ShouldRetry(err error) bool {
return h.retryConfig.IsRetryable(err)
}
// GetUserMessage 获取用户友好的错误消息
func (h *DefaultErrorHandler) GetUserMessage(err error) string {
if ue, ok := err.(*UpdaterError); ok {
return ue.GetUserFriendlyMessage()
}
return "发生未知错误,请联系技术支持"
}