【问题标题】:Is it a problem to pass a single error to errors.Join?将单个错误传递给 errors.Join 是否有问题?
【发布时间】:2023-02-14 02:35:34
【问题描述】:

Go 1.20 引入了可以包装多个错误的errors.Join 函数。调用这个函数并且只传入一个错误有什么问题吗?

例如,this article 建议不要对可写文件使用 defer f.Close() 习惯用法,因为那样会默默地忽略 Close 返回的任何错误。相反,它建议使用命名的返回值 err 来传播 Close 的返回值——除非这样做会覆盖之前的错误:

defer func() {
    cerr := f.Close()
    if err == nil {
        err = cerr
    }
}()

在这种情况下使用 errors.Join 似乎更正确:

defer func() {
    cerr := f.Close()
    err = errors.Join(err, cerr)
}()

如果 errcerr 都不是 nil,这将返回两个错误。如果两者都是nil,它将返回nil

但是,如果一个是 nil 而另一个不是 nil,则 errors.Join 不仅会返回非 nil 错误,还会返回一个 errors.joinError 包装器。像这样包装错误会导致任何问题吗?特别是如果调用堆栈中的多个函数使用这种方法,那么单个错误可能会在多层包装器中结束?

【问题讨论】:

    标签: go error-handling


    【解决方案1】:

    如果 errors.JoinError 只有一个非零错误,那仍然是一个连接错误,并且 errors.Aserrors.Is 函数按预期工作。无论连接错误的嵌套级别如何,这都是正确的。

    唯一的潜在问题是是否有如下代码:

    err:=someFunc()
    if err==io.EOF {
      ...
    }
    

    那么这将失败。必须重写此代码以使用errors.Is

    【讨论】:

      猜你喜欢
      • 2018-03-26
      • 1970-01-01
      • 2021-06-23
      • 1970-01-01
      • 1970-01-01
      • 2022-01-16
      • 1970-01-01
      • 1970-01-01
      • 2021-07-13
      相关资源
      最近更新 更多