如何在Golang中检查两个错误包装是否相等?

huangapple go评论79阅读模式
英文:

how to check if two wrap error are equal in golang?

问题

我在errdefs.go文件中看到了一个简单的错误包装类型:

package errdefs

type errInvalidAttribute struct{ error }

func (e errInvalidAttribute) Unwrap() error {
	return e.error
}

func InvalidAttribute(err error) error {
	if err == nil || IsInvalidAttribute(err) {
		return err
	}
	return errInvalidAttribute{err}
}

func IsInvalidAttribute(err error) bool {
	return errors.As(err, &errInvalidAttribute{})
}

以下是对该文件的单元测试:

package errdefs_test

func TestWrapErrorEqual(t *testing.T) {
	err1 := errdefs.InvalidAttribute(fmt.Errorf("this is a wrap error"))
	err2 := errdefs.InvalidAttribute(fmt.Errorf("this is a wrap error"))
	if err1 != err2 {
		t.Errorf("!= now work")
	}

	if !errors.Is(err1, err2) {
		t.Errorf("errors.Is not work")
	}
}

然后我运行了单元测试:

$ go test .
--- FAIL: TestInvali (0.00s)
    errdefs_test.go:62: != not work
    errdefs_test.go:66: errors.Is not work
FAIL
FAIL	errdefs	0.496s
FAIL

!=errors.Is 的工作不正常,那么在 Golang 中如何检查两个包装错误是否相等呢?

英文:

I have a simple error wrap type in errdefs.go:

package errdefs

type errInvalidAttribute struct{ error }

func (e errInvalidAttribute) Unwrap() error {
	return e.error
}

func InvalidAttribute(err error) error {
	if err == nil || IsInvalidAttribute(err) {
		return err
	}
	return errInvalidAttribute{err}
}

func IsInvalidAttribute(err error) bool {
	return errors.As(err, &errInvalidAttribute{})
}

The following is a unit test of this file:

package errdefs_test

func TestWrapErrorEqual(t *testing.T) {
	err1 := errdefs.InvalidAttribute(fmt.Errorf("this is a wrap error"))
	err2 := errdefs.InvalidAttribute(fmt.Errorf("this is a wrap error"))
	if err1 != err2 {
		t.Errorf(" != now work")
	}

	if !errors.Is(err1, err2) {
		t.Errorf("errors.Is not work")
	}
}

then I run unit-test:

$ go test .
--- FAIL: TestInvali (0.00s)
    errdefs_test.go:62: != not work
    errdefs_test.go:66: errors.Is not work
FAIL
FAIL	errdefs	0.496s
FAIL

!= and errors.Is not work well,so how do I check if two wrap errors are equal in golang?

答案1

得分: 1

等号运算符以及errors.Is函数都是用来检查错误对象的引用是否相等。因此,两个实例化的错误对象永远不会相等。

大多数库在启动时实例化错误变量,并使用引用进行相等性检查。

var (
  ErrInvalidArgument = errors.New("invalid argument")
)

func ErrInvalidArgument(err error) bool {
  return err == ErrInvalidArgument
}

当然,你也可以检查error#Error返回的字符串是否相等,如果它不是动态组装的。

因此,你的测试函数应该如下所示。

func TestWrapErrorEqual(t *testing.T) {
    wrappedErr := fmt.Errorf("this is a wrap error")
    err1 := errdefs.InvalidAttribute(wrappedErr )
    err2 := errdefs.InvalidAttribute(wrappedErr )
    if err1.Unwrap() != err2.Unwrap() {
        t.Errorf(" != now work")
    }

    if !errors.Is(err1.Unwrap(), err2.Unwrap()) {
        t.Errorf("errors.Is not work")
    }
}

希望我理解你的问题,并且这对你有所帮助。

英文:

The equality operator as well as errors.Is check the equality of the references of the error objects. So, two instantiated error objects will never be equal.

Most libraries instantiate error variables on startup and use the references for equality checks.

var (
  ErrInvalidArgument = errors.New("invalid argument")
)

func ErrInvalidArgument(err error) bool {
  return err == ErrInvalidArgument
}

Of course, you can also check the equality of the string returned by error#Error, if it is not dynamically assembled.

So, you test function would look like following.

func TestWrapErrorEqual(t *testing.T) {
    wrappedErr := fmt.Errorf("this is a wrap error")
    err1 := errdefs.InvalidAttribute(wrappedErr )
    err2 := errdefs.InvalidAttribute(wrappedErr )
    if err1.Unwrap() != err2.Unwrap() {
        t.Errorf(" != now work")
    }

    if !errors.Is(err1.Unwrap(), err2.Unwrap()) {
        t.Errorf("errors.Is not work")
    }
}

I hope I got your question right and this is somewhat helpful.

huangapple
  • 本文由 发表于 2021年12月3日 17:36:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/70212161.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定