mco*_*lin 24 error-handling go
我很难在Go中使用自定义错误类型.我阅读了关于错误的博客文章
所以我尝试了这个:
在我的模型中.我定义了一个自定义错误:
type ModelMissingError struct {
msg string // description of error
}
func (e *ModelMissingError) Error() string { return e.msg }
Run Code Online (Sandbox Code Playgroud)
在我的一个方法中,我抛出一个这样的自定义错误:
...
return Model{}, &ModelMissingError{"no model found for id"}
...
Run Code Online (Sandbox Code Playgroud)
在该方法的调用者中,我想检查为其类型返回的错误,如果它实际上是a,则采取措施ModelMissingError.
我怎样才能做到这一点?
我试过这个:
if err == model.ModelMissingError
Run Code Online (Sandbox Code Playgroud)
结果是 *type model.ModelMissingError is not an expression*
显然我错过了一些东西.
bla*_*een 55
要检查错误的类型,请使用errors.As
\n\n\n
As查找 err 链中与目标匹配的第一个错误 [...] \xe2\x80\x8b 如果错误的具体值可分配给目标指向的值,则错误与目标匹配
当然,类型同一性是可分配性的一个条件。
\n所以它看起来像:
\ntarget := &model.ModelMissingError{} \nif errors.As(err, &target) {\n fmt.Println(target) // no model found for id\n}\nRun Code Online (Sandbox Code Playgroud)\n注意&上面例子中的两种用法。这是因为:
\n\n\n
As如果 target 不是指向实现错误的类型或任何接口类型的非零指针,则会发生恐慌。
在您的情况下,您在指针接收器上Error() string声明了方法,因此要满足的“指向实现接口的类型的指针”是。所以你需要解决两次。errorAs**ModelMissingError
另一种方法errors.Is检查值是否相等。
\n\n如果错误等于目标或者实现 Is(error) bool 方法使得 Is(target) 返回 true,则认为错误与目标匹配。
\n
这在例如固定错误值的情况下很有用,例如声明为标准库var或const类似标准库的错误io.EOF。举个例子:
var ErrModelMissing = errors.New("no model found for id")\n\nfunc foo() {\n err := bar()\n if errors.Is(err, ErrModelMissing) {\n fmt.Println(err) // no model found for id\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n考虑一下 Go 1.13 的用处errors.As在于errors.Is错误展开。如果您检查任意长调用堆栈顶部的错误,您必须记住,原始错误可能会在冒泡时被包裹到其他错误中。那么直接检查相等性或类型可分配性是不够的。
err1 := fmt.Errorf("wrapped: %w", &ModelMissingError{})\n target := &ModelMissingError{}\n fmt.Println(errors.As(err1, &target)) // true\n \n err2 := fmt.Errorf("wrapped: %w", FixedError)\n fmt.Println(errors.Is(err2, FixedError)) // true\n fmt.Println(err2 == FixedError) // false\nRun Code Online (Sandbox Code Playgroud)\n此外,该软件包与和github.com/pkg/errors兼容:errors.Aserrors.Is
// import pkgerr "github.com/pkg/errors"\n\nerr3 := pkgerr.Wrap(pkgerr.Wrap(&ModelMissingError{}, "wrapped 1"), "wrapped 2")\nfmt.Println(errors.As(err3, &target)) // true\nRun Code Online (Sandbox Code Playgroud)\n游乐场: https: //play.golang.org/p/FEzggdBLCqq
\n当然,如果您确定错误没有被包装,那么一个好的旧类型断言也可以正常工作:
\nif myerr, ok := err.(*model.ModelMissingError); ok {\n // handle myerr\n}\nRun Code Online (Sandbox Code Playgroud)\n
mco*_*lin 44
啊,我想我明白了.我是个笨蛋.阅读博客文章进一步暴露了一点像这样:
serr, ok := err.(*model.ModelMissingError)
Run Code Online (Sandbox Code Playgroud)
这是逗号确定的成语,显然我需要重新做我的go lang巡演
Mar*_*rez 17
现在使用 Go 1.13,我们可以使用errors包中的以下内容:
if errors.Is(err, model.ModelMissingError) {...}
Run Code Online (Sandbox Code Playgroud)
见博文:https : //blog.golang.org/go1.13-errors
mil*_*onb 14
我已经使用switch语句进行错误断言,如下所示:
err := FuncModelMissingError()
switch t := err.(type) {
default:
fmt.Println("not a model missing error")
case *ModelMissingError:
fmt.Println("ModelMissingError", t)
}
Run Code Online (Sandbox Code Playgroud)
我希望这能够帮到你.
如果您要跨类型验证:
switch err := errorFromFunction(); err.(type) {
case nil:
fmt.Println("No Error Function Executed Successfully")
case *ErrorType1:
fmt.Println("Type1 Error: ", err)
case *ErrorType2:
fmt.Println("Type2 Error", err)
}
Run Code Online (Sandbox Code Playgroud)
如果您知道错误并想要验证:
err, ok := err.(*ErrorType1)
Run Code Online (Sandbox Code Playgroud)
errors.Iserrors.As哨兵错误
var ErrExist = errors.New("file already exists")
var ErrPermission = errors.New("permission denied")
Run Code Online (Sandbox Code Playgroud)
errors.Isif errors.Is(err, ErrNotExist) {
createFile(..)
}
Run Code Online (Sandbox Code Playgroud)
结构化错误
type CustomError struct {
Msg string
}
func (e *CustomError) Error() string
Run Code Online (Sandbox Code Playgroud)
var cusErr *CustomError
if errors.As(err, &cusErr) {
fmt.Print(cusErr.Msg)
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
21120 次 |
| 最近记录: |