为了账号安全,请及时绑定邮箱和手机立即绑定

Go - 如何组合多个错误对象

Go - 如何组合多个错误对象

Go
繁星淼淼 2022-10-24 09:55:04
假设我有以下代码:package libimport (    "errors"    "strconv")var ErrSomething = errors.New("foobar")func SomeFunc(str string) (int, error) {    i, err := strconv.Atoi(str)    if err != nil {        // how to combine ErrSomething with err?        return 0, fmt.Errorf("%w: %w", ErrSomething, err)    }        // do other things, potentially return other errors    return i}如何将返回的错误strconv.Atoi与我的命名错误结合起来ErrSomething。组合的原因是我的用户SomeFunc()可以使用我的错误“常量”检查到底出了什么问题,同时不会丢失有关潜在错误的信息。我读过类似的问题,但通常的答案是这样做:return 0, fmt.Errorf("foobar: %w", err)但是这样我的用户就无法使用检查错误errors.Is(err, ???)
查看完整描述

1 回答

?
富国沪深

TA贡献1790条经验 获得超9个赞

Is您可以通过创建实现和方法的错误类型来实现所需的行为,Unwrap如下所示:


package lib


import (

    "fmt"

    "strconv"

)


type FoobarError struct {

    msg      string

    original error

}


func (err *FoobarError) Error() string {

    return fmt.Sprintf("%s: %s", err.msg, err.original.Error())

}


func (err *FoobarError) Unwrap() error {

    return err.original

}


func (err *FoobarError) Is(target error) bool {

    _, ok := target.(*FoobarError)

    return ok

}


func SomeFunc() error {

    // strconv.ErrSyntax is used as a dummy error here for the error

    // that might be returned by strconv.Atoi or any other operation.

    err := strconv.ErrSyntax

    return &FoobarError{"foobar", err}

}

用法:


package main


import (

    "errors"

    "fmt"

    "strconv"


    "lib"

)


func main() {

    if err := lib.SomeFunc(); err != nil {

        fmt.Println(err)                                // foobar: invalid syntax

        fmt.Println(errors.Is(err, &lib.FoobarError{})) // true

        fmt.Println(errors.Is(err, strconv.ErrSyntax))  // true

    }

}

您可以在此处阅读有关此方法的更多信息。


奖金

与 Go 的os.IsExist类似,您可能有兴趣在库中添加一个帮助函数,以便用户更轻松地检查错误:


package lib


import (

  "errors"

  // ...

)


// ...


func IsFoobar(err error) bool {

    return errors.Is(err, &FoobarError{})

}


用法:


package main


// ...


func main() {

    err := lib.SomeFunc(); 

    if lib.IsFoobar(err) {

      // ...

    }

}


查看完整回答
反对 回复 2022-10-24
  • 1 回答
  • 0 关注
  • 91 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信