猿问

如何设计一个个性化的错误,然后对其进行测试(而不是错误中的描述)?

在Python中,使用自己的“错误类型”引发异常(错误)的典型方法是


class noMoreBeer(Exception):

    pass


try:

    a_function()

except noMoreBeer as e:

    print("there is no more beer ({e}), go buy some")

except Exception as e:

    print(f"unexpected exception happened, namely {e}")

else:

    print("thinks went fine")

我想移植到Go哲学的主要部分是,我创建了自己的例外,它可以有可选的解释文本,但我检查,而不是错误文本。noMoreBeer


现在回到Go,我阅读了几页关于如何处理错误的内容(虽然我首先很生气,但我现在发现它可以更好地编写代码),其中包括Go博客。为此,我试图复制上述内容,但下面的代码不起作用(JetBrain的Goland指向和return Error.noMoreBeer()if err == Error.noMoreBeer())


package main


import "fmt"


type Error interface {

    error

    noMoreBeer() bool

}


func thisFails() Error {

    // returns my specific error, but could also percolate some other errors up

    return Error.noMoreBeer()

}


func main() {

    err := thisFails()

    if err != nil {

        if err == Error.noMoreBeer() {

            fmt.Println("go buy some beer")

        } else {

            panic("something unexpected happened")

        }

    }

}

在 Go 中,有没有办法创建这样的特定错误?


在我的情况下,它们的主要驱动因素之一是我不依赖于错误中传递的文本,而是依赖于[类|无论什么],如果它有拼写错误,那将是一个错误。


炎炎设计
浏览 135回答 4
4回答

达令说

您应该研究四个函数。这是这个主题的官方Go博客文章。它是在Go 1.13中引入的。腾讯网.错误:创建一个包含一些详细信息的新错误。可以使用 包装错误。%w错误。新增:创建一个新的错误类型,可以将其包装并与 Go 1.13 中引入的函数进行比较。错误。是:将错误变量与错误类型进行比较。它可以解开错误包装。错误。As:将错误变量与错误接口实现进行比较。它可以解开错误包装。

婷婷同学_

我第一次尝试解决方案:package mainimport (    "errors"    "fmt")var noMoreBeer = errors.New("no more beer")func thisFails() error {    // returns my specific error, but could also percolate some other errors up    return noMoreBeer}func main() {    err := thisFails()    if err != nil {        if err == noMoreBeer {            fmt.Println("go buy some beer")        } else {            panic("something unexpected happened")        }    }}我理解阅读 https://blog.golang.org/go1.13-errors 的关键点是,我可以针对类型为 .这在功能上等同于我开始使用的Python示例。error

猛跑小猪

我们一直在生产中使用错误,通过cutome实现错误接口,没有任何问题。这有助于检测错误并更有效地找到根本原因。package errorstype Error struct {    err      error // the wrapped error    errType  ErrorType    errInfo  ErrorInfo    op       Op    // domain specific data    userID    int    requestID string}type (    ErrorType string    ErrorInfo string    Op        string)var NoMoreBeer ErrorType = "NoMoreBeerError"func (e Error) Error() string {    return string(e.errInfo)}func Encode(op Op, args ...interface{}) error {    e := Error{}    for _, arg := range args {        switch arg := arg.(type) {        case error:            e.err = arg        case ErrorInfo:            e.errInfo = arg        case ErrorType:            e.errType = arg        case Op:            e.op = arg        case int:            e.userID = arg        case string:            e.requestID = arg        }    }    return e}func (e Error) GetErrorType() ErrorType {    return e.errType}通过这种方式,您可以使用错误,但可以根据需要添加扩展功能。e := errors.Encode(    "pkg.beerservice.GetBeer",     errors.NoMoreBeer,     errors.ErrorInfo("No more beer available"),).(errors.Error)switch e.GetErrorType() {case errors.NoMoreBeer:    fmt.Println("no more beer error")    fmt.Println(e.Error()) // this will return "No more beer available"}操场上的工作示例:https://play.golang.org/p/o9QnDOzTwpc

哈士奇WWW

您可以使用类型开关。package mainimport "fmt"// the interfacetype NoMoreBeerError interface {    noMoreBeer() bool}// two different implementations of the above interfacetype noMoreBeerFoo struct { /* ... */ }type noMoreBeerBar struct { /* ... */ }func (noMoreBeerFoo) noMoreBeer() bool { return true }func (noMoreBeerBar) noMoreBeer() bool { return false }// have the types also implement the standard error interfacefunc (noMoreBeerFoo) Error() string { return " the foo's error message " }func (noMoreBeerBar) Error() string { return " the bar's error message " }func thisFails() error {    if true {        return noMoreBeerFoo{}    } else if false {        return noMoreBeerFoo{}    }    return fmt.Errorf("some other error")}func main() {    switch err := thisFails().(type) {    case nil: // all good    case NoMoreBeerError: // my custom error type        if err.noMoreBeer() { // you can invoke the method in this case block            // ...        }        // if you need to you can inspect farther for the concrete types        switch err.(type) {        case noMoreBeerFoo:            // ...        case noMoreBeerBar:            // ...        }    default:        // handle other error type    }}
随时随地看视频慕课网APP

相关分类

Go
我要回答