Go语言错误分类

错误的分类

在 Go 语言中,错误是通过实现 error 接口的类型表示的,但不同场景下的错误可以按性质和用途进行分类。以下是 Go 语言错误的常见分类,以及每类错误的解释和示例:


标准错误类型

标准库中定义了许多常见的错误类型,用于表示各种常见的错误场景。以下是一些 Go 标准库中常见的错误类型和相关包:

errors.New fmt.Errorf

  • 用于创建自定义的错误。

  • 标准库提供的最基础的错误类型。

示例

Go 复制代码
import ( 
    "errors" 
    "fmt"
) 

err1 := errors.New("this is an error") 
err2 := fmt.Errorf("formatted error: %d", 42)

IO 相关错误

io

  • 包含基础 I/O 操作的错误类型。

常见错误

  • io.EOF:表示流结束(End Of File)。

  • io.ErrUnexpectedEOF:在读取流时遇到意外的 EOF。

  • io.ErrClosedPipe:操作已关闭的管道。

示例

Go 复制代码
import "io" 
if err == io.EOF { 
    fmt.Println("Reached end of file") 
}

文件操作相关错误

os

  • 处理文件系统相关的错误。

常见错误

  • os.ErrNotExist:文件或目录不存在。

  • os.ErrExist:文件或目录已经存在。

  • os.ErrPermission:权限不足。

  • os.ErrInvalid:无效操作。

示例

Go 复制代码
import "os" 

if errors.Is(err, os.ErrNotExist) {
    fmt.Println("File does not exist") 
}

网络相关错误

net

  • 网络操作相关的错误。

常见错误

  • net.InvalidAddrError:无效地址错误。

  • net.UnknownNetworkError:未知网络类型错误。

  • net.AddrError:地址解析错误。

  • net.DNSError:域名解析错误。

示例

Go 复制代码
import "net"

_, err := net.LookupHost("invalid_domain")
if dnsErr, ok := err.(*net.DNSError); ok {
     fmt.Println("DNS error:", dnsErr) 
}

JSON 相关错误

encoding/json

  • JSON 编码和解码的错误。

常见错误

  • json.InvalidUnmarshalError:解码到无效的目标。

  • json.UnmarshalTypeError:JSON 与目标类型不匹配。

示例

Go 复制代码
import "encoding/json" 

var data interface{}
err := json.Unmarshal([]byte("invalid json"), &data) 

if syntaxErr, ok := err.(*json.SyntaxError); ok { 
    fmt.Println("JSON Syntax Error at offset:", syntaxErr.Offset) 
}

HTTP 相关错误

net/http

  • HTTP 请求与响应相关的错误。

常见错误

  • http.ErrHandlerTimeout:HTTP 处理程序超时。

  • http.ErrBodyNotAllowed:HTTP 请求体不被允许。

示例

Go 复制代码
import "net/http" 

if errors.Is(err, http.ErrHandlerTimeout) { 
    fmt.Println("HTTP handler timeout") 
}

时间解析相关错误

time

  • 处理时间解析或格式化错误。

常见错误

  • time.ErrBad:时间字符串格式错误。

示例

Go 复制代码
import "time"

_, err := time.Parse("2006-01-02", "invalid-date")
if err != nil { 
    fmt.Println("Time parsing error:", err) 
}

数据库相关错误

database/sql

  • 数据库操作相关的错误。

常见错误

  • sql.ErrNoRows:查询未返回结果。

  • sql.ErrTxDone:事务已完成,不能再执行操作。

示例

Go 复制代码
import "database/sql" 

if errors.Is(err, sql.ErrNoRows) { 
    fmt.Println("No rows found") 
}

压缩解压相关错误

compress/gzip

  • 用于处理 gzip 格式的错误。

常见错误

  • gzip.ErrHeader:gzip 文件头错误。

加密 解密相关错误

crypto crypto/x509

  • 加密或证书解析相关错误。

常见错误

  • x509.IncorrectPasswordError:密码错误。

  • x509.UnknownAuthorityError:未知的证书颁发机构。


按错误来源分类

应用级错误

应用程序逻辑中定义的错误,如输入验证失败、业务规则不满足等。这些错误通常由程序员明确定义。

示例

Go 复制代码
type ValidationError struct { 
    Field string 
    Msg string 
} 

func (e ValidationError) Error() string { 
    return fmt.Sprintf("validation failed on field %s: %s", e.Field, e.Msg) 
}

系统级错误

系统资源相关的错误,包括文件访问、网络问题等。 示例

Go 复制代码
func readConfig(filename string) error { 
    _, err := os.ReadFile(filename) 
    if err != nil {
        return fmt.Errorf("failed to read config: %w", err) 
    } 
    return nil 
}

第三方库错误

使用第三方库时返回的错误,需要通过文档或代码了解这些错误的含义,并采取适当措施。 示例

Go 复制代码
func sendMessageToKafka() error { 
    err := producer.SendMessage(message) 
    if err != nil { 
        return fmt.Errorf("kafka producer error: %w", err) 
    } 
    return nil 
}

按错误处理方式分类

可恢复错误

可以通过重新尝试或特定逻辑处理恢复的错误。 示例

Go 复制代码
func retryOperation(attempts int) error { 
    for i := 0; i < attempts; i++ {
        err := doSomething() 
        if err == nil { 
            return nil 
        } 
        time.Sleep(1 * time.Second) // 等待后重试 
    } 
    return fmt.Errorf("operation failed after %d attempts", attempts) 
}

不可恢复错误

表示程序的逻辑或系统的严重错误,无法通过重新尝试解决,如非法状态、编程错误等。

示例

Go 复制代码
func mustDivide(a, b int) int { 
    if b == 0 { 
        panic("division by zero") 
    } 
    return a / b 
}

按错误语义分类

用户输入错误

用户提供的输入不满足预期导致的错误。

示例

Go 复制代码
func validateInput(input string) error { 
    if input == "" {
        return fmt.Errorf("input cannot be empty") 
    } 
    return nil 
}

数据处理 错误

数据格式、解析、转换等问题。

示例

Go 复制代码
func parseInt(value string) (int, error) { 
    num, err := strconv.Atoi(value) 
    if err != nil { 
        return 0, fmt.Errorf("failed to parse integer: %w", err) 
    } 
    return num, nil 
}

网络/ IO 错误

网络连接失败、超时、文件系统操作失败等问题。

示例

Go 复制代码
func fetchData(url string) ([]byte, error) { resp, err := http.Get(url) if err != nil { return nil, fmt.Errorf("failed to fetch data: %w", err) } defer resp.Body.Close() return io.ReadAll(resp.Body) }

业务逻辑错误

业务逻辑不满足需求导致的错误。

示例

Go 复制代码
func checkAccountBalance(balance, withdrawAmount float64) error { 
    if withdrawAmount > balance { 
        return fmt.Errorf("insufficient balance") 
    } 
    return nil 
}

按错误表现分类

明确错误

明确的错误通过 error 接口表示,并具有清晰的语义。

示例

Go 复制代码
return fmt.Errorf("unable to connect to database: %w", err)

模糊错误

返回的错误缺乏上下文信息,不利于调试。

示例

Go 复制代码
return errors.New("something went wrong") // 不清楚具体问题是什么

总结

Go 中的错误分类可以帮助开发者更清晰地理解错误的来源和性质,从而制定合理的处理策略。推荐:

  1. 使用明确的错误上下文。

  2. 尽量细化错误类型,尤其是应用级错误。

  3. 使用 errors.Iserrors.As 对错误进行分类处理。

  4. 在必要的场景下记录日志,但不要重复记录错误信息。

相关推荐
.猫的树10 分钟前
Java集合List快速实现重复判断的10种方法深度解析
java·开发语言·list·集合
刀客12315 分钟前
C++ STL(三)list
开发语言·c++
朔北之忘 Clancy1 小时前
2022 年 12 月青少年软编等考 C 语言五级真题解析
c语言·开发语言·c++·学习·算法·青少年编程·题解
折枝寄北1 小时前
(21)从strerror到strtok:解码C语言字符函数的“生存指南2”
c语言·开发语言
m0_748236581 小时前
PHP进阶-在Ubuntu上搭建LAMP环境教程
开发语言·ubuntu·php
CoderCodingNo1 小时前
【GESP】C++二级模拟 luogu-b3995, [GESP 二级模拟] 小洛的田字矩阵
开发语言·c++·矩阵
pianmian11 小时前
python绘图之swarmplot分布散点图
开发语言·python
Jelena157795857922 小时前
爬虫获取微店商品快递费 item_feeAPI 接口的完整指南
开发语言·前端·爬虫
无极工作室(网络安全)2 小时前
小白向-用python实现快速排序
开发语言·python
k要开心2 小时前
C语言综合案例:学生成绩管理系统
c语言·开发语言