错误处理分支里先判断 `if err != nil` 再打日志,结果在这一行 panic:`invalid memory address or nil pointer dereference`,err 看着确实不是 nil,日志根本没机会写出来,事后也没能补上上下文。碰到这种情况,我一般先确认改动有没有真的生效。

原因不复杂,函数返回的是自定义错误指针类型,指针为 nil 时赋给 error 接口,接口的类型信息不为空,整个接口就不等于 nil,判断成立后调用方法就解引用了空指针。

「typed nil 判断」相关的日志我一般连着看前后五分钟,单看一条报错经常判断不出是哪一步失败。别只看报错的最后一行,往上看几行,真正的起因通常在上面。

go vet ./...
grep -n 'return .*Err{}' -r .
grep -n 'return nil' -r .

同类问题如果隔一段时间又出现,多半是某个定时任务或重启流程把改动冲掉了。

具体做法是,用错误断言取出具体类型再判断它是否为空;返回的地方直接返回空值而不是空指针变量;给这类函数补一条覆盖空错误路径的单元测试。

最后用这个标准收尾,构造一条返回空指针的错误路径,判断不再进入分支,也没有再触发 panic。

作者 9823189