包装后的错误始终为 nil¶
ID: go/unexpected-nil-value
Kind: problem
Security severity:
Severity: warning
Precision: high
Tags:
- reliability
- correctness
- logic
Query suites:
- go-security-and-quality.qls
pkg.errors
包提供 errors.Wrap
函数,用于使用堆栈跟踪注释错误。当传递 nil
时,此函数返回 nil
。当 errors.Wrap
的第一个参数*始终*为 nil
时,函数调用无效,并且可能表示编程错误。一个常见的例子是,当 errors.Wrap(err, "message")
调用从同一个函数中较早的错误处理块复制,并在不检查其保护中的 err
的后续错误处理块中使用时。在这种情况下,向调用方返回 nil
值按照惯例表示操作成功,因此错误被掩盖了。
建议¶
通常,err
值在其预期范围之外被引用。可以通过删除该引用来解决此问题,例如,将 errors.Wrap(err, "message")
形式的调用更改为 errors.New("message")
。
示例¶
下面的示例展示了一个示例,其中从对 f1
的调用返回的 err
值在后面的调用中被重用,而此时已知它是 nil
package main
import (
"github.com/pkg/errors"
)
func f1(input string) error {
if input == "1" {
return errors.Errorf("error in f1")
}
return nil
}
func f2(input string) (bool, error) {
if input == "2" {
return false, errors.Errorf("error in f2")
}
return true, nil
}
func test1(input string) error {
err := f1(input)
if err != nil {
return errors.Wrap(err, "input is the first non-negative integer")
}
if ok2, _ := f2(input); !ok2 {
return errors.Wrap(err, "input is the second non-negative integer")
}
return nil
}
解决此问题的一种方法是使用 errors.New
创建一个新的错误值
package main
import (
"github.com/pkg/errors"
)
func f1(input string) error {
if input == "1" {
return errors.Errorf("error in f1")
}
return nil
}
func f2(input string) (bool, error) {
if input == "2" {
return false, errors.Errorf("error in f2")
}
return true, nil
}
func test1(input string) error {
err := f1(input)
if err != nil {
return errors.Wrap(err, "input is the first non-negative integer")
}
if ok2, _ := f2(input); !ok2 {
return errors.New("input is the second non-negative integer")
}
return nil
}
参考¶
Go 错误,github.com/pkg/errors: errors.Wrap