关于golang中的错误处理机制的详细介绍
时间:2019-12-07 09:36
基础 错误处理应该是工程的一部分,Golang中的error是一个 凡是实现 直接返回错误 直接返回错误,类似于直接返回字符串类型的错误,或者错误码之类的。字符串类型的错误,在基础部分提到了。错误码相当于Linux、C编程中的错误码,一般我们需要自己定义。举个例子: 这种类型的错误,编写简单,但是有两个缺陷: 1、外层如果想要使用错误码,则需要引入这个包,容易出现循环引用的情况。 2、如果包内部修改返回的错误码类型,则外部使用到错误码的地方,都要进行相应的修改,破坏了封闭性。 对于第一个缺陷,可以使用一个第三方的包,专门存放错误码,这个方式值得商榷。永远不要通过判断Error()方法返回的字符串的值,来进行对应的错误处理!!! 返回自定义类型的错误 该方式可以返回自定义的类型,并通过断言自定义类型,来进行有关的错误处理;自定义类型可以携带更多的信息,代码实例: 这种方式处理问题更加方便,但是仍然可能会有包循环引用的问题。 隐藏内部细节的错误处理 上述两种方式,可以适应一些场景,不过都无法解决可能存在循环依赖的问题。为此,我们使用 如果有一个现成的error,我们需要对他进行再次包装处理,这时候有三个函数可以选择。 其实上面的包装,很类似于Java的异常包装,被包装的error,其实就是Cause,在前面的章节提到错误的根本原因,就是这个Cause。所以这个错误处理库为我们提供了Cause函数让我们可以获得最根本的错误原因。 使用for循环一直找到最根本(最底层)的那个error。 相关文章教程推荐:golang教程 以上就是关于golang中的错误处理机制的详细介绍的详细内容,更多请关注gxlsystem.com其它相关文章!interface
类型,如下:type error interface {
Error() string
}
Error()
方法的结构,都可以作为错误处理。因此如果函数可能出现错误,那么可以在返回值的最后,返回一个错误,比如:func foo() error {
// ... do something
return errors.New("foo error")
}
package mypkg
type ErrCode int
const (
ERR1 = 1
ERR2 = 2
ERR3 = 3
)
func sub(a, b int) (int, ErrCode) {
if b < 0 {
return 0, ERR1
} else if a < b {
return 0, Err2
} else if a < 0 {
return 0, Err3
}
return a - b
}
package main
import (
"errors"
"fmt"
"runtime/debug"
)
type MyError struct {
Inner error // 内粗错误
Message string // 自定义错误信息
StackTrace string // 堆栈信息
Misc map[string]interface{} //其它的一些数据
}
func (myError MyError) Error() string {
return myError.Message
}
func wrapError(err error, msg string, msgArgs ...interface{}) MyError {
return MyError{
Inner: err,
Message: fmt.Sprintf(msg, msgArgs),
StackTrace: string(debug.Stack()),
Misc: make(map[string]interface{}),
}
}
func Handle(key int) error {
if key < 0 {
return wrapError(errors.New("key < 0"), "This is an error test")
}
return nil
}
func main() {
if err := Handle(-1); err != nil {
if e, ok := err.(MyError); ok {
fmt.Printf("Inner: %v, Message: %v, StackTrace: %v\n",
e.Inner, e.Message, e.StackTrace) // 这里输出对应的数据
}
}
}
github.com/pkg/errors
的包来解决问题,给出一个代码实例。func New(message string) error
//只附加新的信息
func WithMessage(err error, message string) error
//只附加调用堆栈信息
func WithStack(err error) error
//同时附加堆栈和信息
func Wrap(err error, message string) error
func Cause(err error) error {
type causer interface {
Cause() error
}
for err != nil {
cause, ok := err.(causer)
if !ok {
break
}
err = cause.Cause()
}
return err
}