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. 在必要的场景下记录日志,但不要重复记录错误信息。

相关推荐
雯0609~23 分钟前
PHP:上传图片的图片压缩
android·开发语言·php
Amo 67291 小时前
取消网络请求
开发语言·前端·javascript
未来之窗软件服务1 小时前
软件架构设计——通用表单UI—未来之窗行业应用跨平台架构
开发语言·javascript·ui
编程零零七1 小时前
【Python】tensorflow中的argmax()函数
开发语言·python·信息可视化·数据分析·arm·python学习·python数据可视化
嘉琪0011 小时前
js相关面试题
java·开发语言
iiiiiankor1 小时前
【C语言实现:用队列模拟栈与用栈模拟队列(LeetCode 225 & 232)】
c语言·开发语言·leetcode··队列
精神病不行计算机不上班1 小时前
[C++]纯虚函数与虚函数
开发语言·c++
oVo5671 小时前
Rust 宏
开发语言·算法·rust
minos.cpp1 小时前
Rust之抽空学习系列(三)—— 编程通用概念(中)
开发语言·学习·rust
喜欢打篮球的普通人2 小时前
对rust的全局变量使用drop方法
开发语言·后端·rust