errcheck 默认跳过 _test.go 文件,需在 .golangci.yml 的 run 区块显式配置 tests: true 并启用 errcheck,否则对 t.Fatal(err) 等测试内 error 忽略完全静默。

errcheck 默认不检查 test 文件,必须显式开启
errcheck 的默认行为是跳过 _test.go 文件,哪怕你写了 t.Fatal(err) 或 require.NoError(t, err),它也视而不见。这不是 bug,是设计如此——但团队写测试时漏处理 error 的概率并不比业务代码低。
要让它检查测试文件,必须在 .golangci.yml 中启用 tests: true(注意:这是全局 run 配置项,不是 errcheck 专属):
run:
tests: true
linters:
enable:
- errcheck
漏掉这行,errcheck 就只扫 .go,对 xxx_test.go 完全静默。
errcheck 不报错的常见原因:函数返回值被赋给了空白标识符
errcheck 的核心逻辑是「检测函数调用后,error 类型返回值是否被显式使用」。但它对 _ = someFunc() 这种写法默认放行——它认为你是有意忽略。
如果你希望连这种显式忽略都报警(比如强制要求加注释说明理由),需启用 check-blank: true:
linters-settings:
errcheck:
check-blank: true
-
check-blank: false(默认):忽略_ = f() -
check-blank: true:把_ = f()当作未处理 error 报告 - 搭配
exclude-rules可白名单豁免特定调用,例如:text: "^_ = os\.Remove.*"
errcheck 和 govet 的职责边界容易混淆
两者都会报告 error 使用问题,但触发条件完全不同:
-
govet只查「明显无意义的 error 忽略」,比如json.Unmarshal(b, &v)后完全不看返回值,且该 error 没被任何变量接收 -
errcheck更激进:只要函数签名含error返回,且调用后没被任何非_变量接收,就报 - 典型冲突场景:
log.Printf(...)返回(int, error),govet不管,errcheck会报——但实际中你根本不会处理它的 error
所以生产配置里常配合 exclude-rules 过滤掉这类“已知可忽略”:
issues:
exclude-rules:
- path: ".*"
text: "log\.(Print|Fatal|Panic)\("
- path: ".*"
text: "fmt\.Print.*"
CI 中 errcheck 失效,大概率是 --out-format 或退出码没配对
errcheck 发现问题时默认退出码为 1,但 CI 流程里如果命令没失败、或报告格式不对,问题就会被吞掉。
- GitHub Actions 必须加
--out-format=github-actions,否则报错只打在日志里,PR 上不标红 - GitLab CI 或 Jenkins 建议用
--out-format=json --print-issued-lines=true,再用脚本解析 - 本地调试时加
--fix无效——errcheck不支持自动修复,别浪费时间试
最隐蔽的坑:CI 脚本里写了 golangci-lint run 却没加 --config=.golangci.yml,此时 errcheck 根本不运行,你看到的“零报错”其实是“压根没检查”。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











