【问题标题】:How to know variable name adhering to go error如何知道变量名坚持去错误
【发布时间】:2022-11-14 21:02:15
【问题描述】:

使用 go 时,有一种模式用于定义错误并以(对我而言)非常特殊的方式处理它们。通常错误声明为ErrorSomethingWentWrong = errors.New("Just an example!")。您可以使用errors.Is(err, ErrorSomethingWentWrong) 来捕获该特定错误。 Is 函数可以通过比较指针来做到这一点。但是为了进行比较,我需要知道使用哪个变量名来定义errorString,这样我就可以使用errors.Is 来捕获它。

例如:

ErrorSomethingWentWrong = errors.New("Just an example!")
func DoSomething() (*Something, error) {
    return nil, ErrorSomethingWentWrong
}

我知道字符串 "Just an example!" 返回错误,但我不知道它有变量名 ErrorSomethingWentWrong

func checkError() {
    if errors.Is(err, ErrorSomethingWentWrong){ // how to know this???
       //handle error
    }
}

当我使用errors.Is(err, ErrorSomethingWentWrong) 时,我可以捕捉到这个错误并处理它。使用调试时,我看不到 errorString 代表 ErrorSomethingWentWrong 变量。但是当我不知道变量名是ErrorSomethingWentWrong 时,我需要对代码进行逆向工程或阅读文档以了解返回的是哪个错误。

那么如何知道使用调试或反射来检索错误变量名呢?

【问题讨论】:

  • Go 值和它可能存储在其中的变量名称没有任何联系。给定一个值,您无法判断哪些变量存储该值,可能有多个、一个或根本没有。 db.ErrorNotFound 的值可以存储在名为db.ErrorFound 的变量中。再次,没有联系。请查阅您正在使用的 API 或包的文档,文档应该涵盖这些内容。
  • @icza 我同意并理解。但是errors.Is() 如何根据变量名区分错误呢?当没有文档并且使用的库是一个黑盒子时,我应该如何嗅探这个变量名。
  • errors.Is() 是一个函数,Go价值观传递给它,而不是变量名。 errors.Is(err, db.ErrorNotFound) 接收 2 个值,该值存储在 errdb.ErrorNotFound 变量中。 errors.Is() 作用于值,而不是变量名。 errors.Is() 检查存储在err 中的值是否是存储在db.ErrorNotFound 变量中的值或包装了该值。
  • @icza感谢您的回答,您是对的,它正在比较值。但是这go.dev/play/p/WjFsCaKdHJG 怎么可能呢?两个具有完全相同值的错误,仍然可以区分。是否可以比较指针是否相等?这是辉煌的。但是现在我仍然需要变量名来指向指针。 (对不起,我不是 C 程序员,指针的概念对我来说是新的)
  • 是的,errors.New() 故意创建新的、不同的错误值,即使使用相同的文本也是如此。它通过使用指针来实现。

标签: go design-patterns error-handling


【解决方案1】:

如果我理解正确,这是你的场景:

您从包中收到一个错误,并且没有文档可以为您提供您应该处理的错误。您正在调试,并看到 errors.errorString,但不知道是否有可以比较的全局和公共错误值。

不幸的是,这是一个值,调试器无法告诉您这是否是全局变量,或者如果是,是哪个,因为您没有收到变量,只有一个值。

你可以:

  • 通读您正在调用的包的源代码,查看返回了哪些错误以及如何处理它们
  • 在源代码中搜索错误字符串中的文本,这可以帮助您查明定义或创建错误的位置。

如果事实证明您希望处理的特定错误未在全局范围内定义(并且重写包对您的情况不可行),那么您将无法处理它。如果有人在函数内使用 errors.New(不好的做法),就会发生这种情况。那么你也可以试试这些:

func handleError(err error) {
    if err.Error() == "full error string" {}

    if strings.Contains(err.Error(), "partial error string") {}
}

但这些都是丑陋的恕我直言。

TL;博士这是不可能的,你必须阅读源代码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多