gogf / gf

GoFrame is a modular, powerful, high-performance and enterprise-class application development framework of Golang.
https://goframe.org
MIT License
11.8k stars 1.61k forks source link

errors/gerror: The judgment result of gerror's Is() method is a bit counter-intuitive #3633

Closed lingcoder closed 5 months ago

lingcoder commented 6 months ago

Go version

go version go1.22.3 windows/amd64

GoFrame version

2.7.1

Can this bug be reproduced with the latest release?

Option Yes

What did you do?

这是gerror的源码部分: func Is(err, target error) bool { if e, ok := err.(IIs); ok { return e.Is(target) } return false } 由于标准库错误没有实现IIs接口,导致这里的判断直接变成false了。 参考下面的标准库的错误包 与 github.com/pkg/errors包的 判断对比。

What did you see happen?

image 我预期与标准库的errors.Is判断结果一致

What did you expect to see?

结果相反

这是复现示例代码:

package main

import (
    "errors"
    "github.com/gogf/gf/v2/errors/gerror"
    pkgerror "github.com/pkg/errors"
    "github.com/stretchr/testify/assert"
    "testing"
)

var ErrNotFound = errors.New("not found")

func TestGerrorIs(t *testing.T) {
    assert.True(t, pkgerror.Is(ErrNotFound, ErrNotFound), "pkg error 判断错误")
    assert.True(t, errors.Is(ErrNotFound, ErrNotFound), "std error 判断错误")
    assert.True(t, gerror.Is(ErrNotFound, ErrNotFound), "gerror 判断错误")

}
oldme-git commented 6 months ago

33ad0ef30f01ba6a24eb13d139ba9b3 error.is 对应的应该是 gerror.Equal

Issues-translate-bot commented 6 months ago

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


33ad0ef30f01ba6a24eb13d139ba9b3 error.is should correspond to gerror.Equal

hailaz commented 6 months ago

err1 := errors.New("permission denied")
fmt.Println(gerror.Is(err1, err1))// false
fmt.Println(gerror.Is(gerror.Wrap(err1, ""), err1))// 这样套一套能返回true,但有点多此一举

func Is(err, target error) bool {
    if e, ok := err.(IIs); ok {
        return e.Is(target)
    }
    return false // 这里不应该直接返回
}
lingcoder commented 6 months ago
err1 := errors.New("permission denied")
fmt.Println(gerror.Is(err1, err1))// false
fmt.Println(gerror.Is(gerror.Wrap(err1, ""), err1))// 这样套一套能返回true,但有点多此一举

func Is(err, target error) bool {
  if e, ok := err.(IIs); ok {
      return e.Is(target)
  }
  return false // 这里不应该直接返回
}

对的,同一个错误,Is都返回false,挺反直觉的