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)

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

相关推荐
踏着七彩祥云的小丑11 小时前
Go学习第4天:条件、循环语句+函数
学习·golang·go
tyung1 天前
Go 手写 Wait-Free SPSC 无界队列:无 CAS、无锁、泛型节点池
数据结构·后端·go
踏着七彩祥云的小丑2 天前
Go学习第3天:变量+常量+运算符
开发语言·学习·golang·go
踏着七彩祥云的小丑3 天前
Go学习第2天:程序结构+基础语法+数据类型
开发语言·学习·golang·go
吴佳浩3 天前
AI Infra 的真相:Go 没输,rust也不是取代
后端·rust·go
2601_959644893 天前
2026年权威AI引擎优化服务咨询,专业之选
go
逐光老顽童3 天前
用 Go 实现一个 LLM 路由网关:Thompson Sampling 与自适应故障转移实践
vue.js·go
蓝宝石的傻话4 天前
MiBeeNvr v0.6.0: 延时摄影 + 转码界面 + ONVIF 增强 + 文档重构
go·github
先跑起来再说4 天前
Go 排行榜系统的工程化实现:分布式锁、快照表与定时刷新
分布式·go·gin
SenChien4 天前
Golang入门学习笔记
golang·go