猿问

是否有一种标准方法来对自定义错误类型进行分类

是否存在用于将自定义错误类型分组在一起的可接受模式,以便我可以根据它们的组以不同方式处理它们?


例如,以下是我在 C# 中的例外情况:


abstract class FriendlyException : ApplicationException {

    protected FriendlyException(string message) : base(message) { }

}

class MyNiceException : FriendlyException {

    public MyNiceException(string message) : base(message) { }

}

catch然后我可以根据它是否属于该类别来做一些不同的事情:


try { DoSomething(); }

catch (FriendlyException ex) { Console.WriteLine(ex.Message); }

catch { Console.WriteLine("Unhandled error"); }

在 Go 中,我看到我可以As直接在类型上使用或切换,但由于存在隐式接口,我看不出这可以在没有浪费接口成员的情况下完成,如下所示:


type FriendlyError interface { SomeWastedMethod() }

type MyFriendlyError struct {}

func (fe MyFriendlyError) SomeWastedMethod() {}

func (fe MyFriendlyError) Error() string { return "implementing error interface" }

然后我可以检查该组是否有错误,如下所示:


var fe FriendlyError

err := DoSomething()

if err != nil {

    if errors.As(err, &fe) {

        fmt.Println(err.Error())

    } else {

        fmt.Println("Unhandled error")

    }

}

结构中浪费的方法MyFriendlyError让我很困扰。这是完成此任务的唯一方法,还是有其他一些标准模式?


在我的示例中,我想要多种不同的错误类型,其中一些可以安全地将消息返回给调用者,而其中一些我只想给调用者一个通用消息,同时仍保留内部日志记录的详细信息。


陪伴而非守候
浏览 104回答 1
1回答

慕田峪9158850

我建议采用以下方式:package mainimport (    "errors"    "fmt")var (    ErrInvalidMsg   = errors.New("invalid message")    ErrInvalidParam = errors.New("invalid param")    ErrBadMsg       = errors.New("bad message"))type GroupError1 struct {    Base error}func (ge GroupError1) Error() string {    return ge.Base.Error()}type GroupError2 struct {    Base error}func (ge GroupError2) Error() string {    return ge.Base.Error()}func TheError(n int) error {    switch n % 3 {    case 0:        return GroupError2{            Base: ErrBadMsg,        }    case 1:        return GroupError1{            Base: ErrInvalidParam,        }    case 2:        return GroupError1{            Base: ErrInvalidMsg,        }    }    return nil}func main() {    if err := TheError(1); err != nil {        var ge1 GroupError1        var ge2 GroupError2        if ok := errors.As(err, &ge1); ok {            fmt.Println("error group 1")        } else if ok := errors.As(err, &ge2); ok {            fmt.Println("error group 2")        } else {            fmt.Println("no error group")        }    }}这里我定义了两个错误组,所以我们可以检测它们errors.As,你不需要定义任何未使用的接口,但你需要手动创建它们并且没有任何自动分组。
随时随地看视频慕课网APP

相关分类

Go
我要回答