GO错误处理【5】显式错误处理

按照上一章的说法,我所有的函数方法都要后面加一个err?

要不然没法一层一层往上传递?

你抓到 Go 语言的"命脉"了!是的,在 Go 赛道,几乎所有涉及 IO、数据库、网络或复杂业务的函数,标配都是返回 (数据, error)

这确实和 PHP 习惯"直接返回数据,出事抛异常"不一样。在 Go 里,这叫"显式错误处理"。

1. 为什么要一层层往上交?

想象你在 PHP 里:

复制代码
// PHP 逻辑
function getInfo() {
    return $db->query(); // 如果这里崩了,直接炸到顶层,中间的逻辑管不住
}

而在 Go 里,这就是一场接力赛:

  • Repo 层:拿到最原始的错,包一下,交给 Logic。
  • Logic 层:看看这个错能不能救(比如读缓存),救不了,再包一下上下文,交给 Handler。
  • Handler 层:最后拍板,是给用户看"系统维护",还是记录一条"严重报警"。

如果没有每一层后面的 error,这个接力棒就断了,顶层根本不知道底层发生了什么,也就没法写出有意义的日志。

2. 难道所有函数都要加 err 吗?

不一定。你可以根据"有没有可能失败"来判断:

  • 需要加 err 的(涉及外部环境):
    • 查数据库、读写文件、调远程接口、解析 JSON、字符串转数字。
    • 准则:只要这个函数依赖"运气"(环境、网络、用户输入),就得带 err
  • 不需要加 err 的(纯逻辑运算):
    • 计算两个数之和、拼接两个字符串、从结构体里取一个已经存在的字段。
    • 准则:只要这个函数是"确定性"的,给同样的输入一定有同样的输出,就不需要 err

3. 写起来会不会很累?

刚开始你会觉得 if err != nil 写得手酸,但你会发现这种写法带来的安全感:

  1. 没有隐藏炸弹:你盯着代码看,哪里有 err 哪里就有风险,一目了然,不需要猜哪里会抛异常。
  2. 强制思考:Go 强制你面对错误。PHP 里你可能会忘了 try-catch,但 Go 里如果你忽略了返回的 err,编译器或静态检查工具会跳出来提醒你。

4. 报错链条实战总结

你可以把这套公式背下来:

  1. 底层 (Repo): return nil, fmt.Errorf("repo context: %w", err)
  2. 中层 (Logic): return nil, fmt.Errorf("logic context: %w", err)
  3. 顶层 (Handler): infra.Log("api").Error("final message", "err", err)

这就是你之前担心的"日志白写了"的终极答案: 底层和中层只负责"攒信息",顶层负责"按开关写日志"。

相关推荐
jeff聊企业数字化2 小时前
私有化即时通讯选型指南:兼顾安全与高效
go·业界资讯·即时通讯
审判长烧鸡3 小时前
GO错误处理【6】显式哲学
go·显式哲学
审判长烧鸡4 小时前
GO错误处理【3】返回err与日志的结合
go·架构设计·报错处理
审判长烧鸡7 小时前
GO裸奔【1】动态SQL
go·动态sql·切片
审判长烧鸡17 小时前
GO时区【2】跨时区应用
go·存储·时区
审判长烧鸡18 小时前
Go结构体与指针【2】接收者应该怎么用
go·指针·结构体·接收者
王中阳Go21 小时前
2026年了,还在纠结后端转AI要不要死磕Python?试试Go吧
后端·go·ai编程
审判长烧鸡1 天前
GO结构体与指针【1】什么时候用指针
go·指针·结构体
审判长烧鸡1 天前
GO错误处理【2】os.Exit(1)/panic/返回err的应用场景
go·异常处理·panic