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

假设我有以下代码:


package lib


import (

    "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, ???)


繁星淼淼
浏览 92回答 1
1回答

富国沪深

Is您可以通过创建实现和方法的错误类型来实现所需的行为,Unwrap如下所示:package libimport (    "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 mainimport (    "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 libimport (  "errors"  // ...)// ...func IsFoobar(err error) bool {    return errors.Is(err, &FoobarError{})}用法:package main// ...func main() {    err := lib.SomeFunc();     if lib.IsFoobar(err) {      // ...    }}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go