如何知道变量名是否存在错误

问题描述 投票:0回答:2

使用 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 design-patterns error-handling
2个回答
1
投票

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

您收到来自包的错误,并且没有文档为您提供应处理的错误。您正在调试,并看到

errors.errorString
,但不知道是否有可以比较的全局和公共错误值。

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

您可以:

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

如果事实证明您希望处理的特定错误未在全局范围内定义(并且重写包对于您的情况不可行),那么您将无法处理它。如果有人在函数内使用

errors.New
,就会发生这种情况(不好的做法)。那么你也可以尝试这些:

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

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

但恕我直言,这些都很丑。

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


0
投票

需要记住的一件事是,错误可能根本不是变量,而只是值。例如,可以这样做:

func foo() error {
    ...
    if somethingWrong {
        return fmt.Errorf("some error")
    }
    ...

另一件事是错误变量可能是私有的(即以小写字母开头)。

© www.soinside.com 2019 - 2024. All rights reserved.