CodeQL 文档

包装后的错误始终为 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

点击查看 CodeQL 代码库中的查询

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
}

参考

  • ©GitHub, Inc.
  • 条款
  • 隐私