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

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

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

Go
陪伴而非守候 2023-03-15 14:37:53
是否存在用于将自定义错误类型分组在一起的可接受模式,以便我可以根据它们的组以不同方式处理它们?例如,以下是我在 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 FriendlyErrorerr := DoSomething()if err != nil {    if errors.As(err, &fe) {        fmt.Println(err.Error())    } else {        fmt.Println("Unhandled error")    }}结构中浪费的方法MyFriendlyError让我很困扰。这是完成此任务的唯一方法,还是有其他一些标准模式?在我的示例中,我想要多种不同的错误类型,其中一些可以安全地将消息返回给调用者,而其中一些我只想给调用者一个通用消息,同时仍保留内部日志记录的详细信息。
查看完整描述

1 回答

?
慕田峪9158850

TA贡献1794条经验 获得超7个赞

我建议采用以下方式:


package main


import (

    "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,你不需要定义任何未使用的接口,但你需要手动创建它们并且没有任何自动分组。



查看完整回答
反对 回复 2023-03-15
  • 1 回答
  • 0 关注
  • 71 浏览
慕课专栏
更多

添加回答

举报

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