errcheck 报“error not checked”是指函数返回 error 类型但未被显式处理:既未赋值、也未用 _ 忽略,更未传递给 log.Fatal 等函数;必须让每个 error “被看见”,而非盲目忽略。

errcheck 报的 "error not checked" 到底在报什么
它只盯一个动作:函数返回 error 类型,但你没做任何处理——既没赋值给变量,也没用 _ 显式忽略,更没传给其他函数(比如 log.Fatal(err))。常见触发点包括:os.Open、json.Unmarshal、http.Get、io.Copy、db.QueryRow.Scan。注意:不是所有 error 返回都要 panic 或重试,但必须“被看见”。
为什么本地 run 没报,CI 却一堆 errcheck 错误
三处必查:
-
.golangci.yml文件名是否拼错?必须是.golangci.yml(不是.golangci.yaml或golangci.yml) - 该文件是否和
go.mod在同一目录?monorepo 中每个 module 都要单独放一份,不能只在根目录放一个 - CI 脚本里是否漏了
--config=.golangci.yml?golangci-lint run默认不读配置,不加参数就等于只跑默认启用的几个 linter(govet和errcheck是默认开的,但若配置失效,errcheck实际不会运行)
怎么修复 errcheck 报警:不是全用 _ 忽略就完事
盲目加 _ = xxx() 是最差解法,它掩盖问题而非解决。正确做法分场景:
- 业务不可恢复错误(如配置文件读取失败)→ 直接
log.Fatal(err)或os.Exit(1) - I/O 类临时错误(如网络请求、数据库查询)→ 用
if err != nil分支处理,至少记录日志,必要时重试或返回用户友好错误 - 明确可忽略的场景(如
os.Remove删除临时文件,删不掉也无所谓)→ 写成_ = os.Remove("tmp.txt"),但得加注释说明理由 - 测试代码里想跳过检查 → 用
//nolint:errcheck行注释,别全局禁用
errcheck 本身不报错但 CI 还是过不了?看 exit code
golangci-lint run 默认即使发现 error 也返回 0,CI 就当成功。必须在 .golangci.yml 里设:issues-exit-code: 1。否则你看到一堆 SA1019 和 errcheck 报警,CI 却绿着,纯属假象。
真正难的不是写 if err != nil,而是判断这个 error 值不值得传播、要不要影响控制流、有没有上下文可补充。这些没法靠工具自动补全,得人看调用链和错误语义。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











