if
func main() {
    conent,err:=ioutil.ReadFile("filepath")
    if err !=nil{
        //错误处理
    }else {
        fmt.Println(string(conent))
    }
}
errornilnil

error 接口

error
// The error built-in interface type is the conventional interface for
// representing an error condition, with the nil value representing no error.
type error interface {
    Error() string
}
Errorerror
type fileError struct {
}

func (fe *fileError) Error() string {
    return "文件错误"
}

自定义 error

fileErrorerror
func main() {
    conent, err := openFile()
    if err != nil {
        fmt.Println(err)
    } else {
        fmt.Println(string(conent))
    }
}

//只是模拟一个错误
func openFile() ([]byte, error) {
    return nil, &fileError{}
}
文件错误
Error
type fileError struct {
    s string
}

func (fe *fileError) Error() string {
    return fe.s
}
fileError
//只是模拟一个错误
func openFile() ([]byte, error) {
    return nil, &fileError{"文件错误,自定义"}
}
fileError
//blog:www.flysnow.org
//wechat:flysnow_org
func New(text string) error {
    return &errorString{text}
}

type errorString struct {
    s string
}

func (e *errorString) Error() string {
    return e.s
}
Newerrors.Newerror

存在的问题

虽然Go语言对错误的设计非常简洁,但是对于我们开发者来说,很明显是不足的,比如我们需要知道出错的更多信息,在什么文件的,哪一行代码?只有这样我们才更容易的定位问题。

errorErrorerrors.New
cause

解决问题

errorString
type stack []uintptr
type errorString struct {
    s string
    *stack
}
flysnow_org
stack
//blog:www.flysnow.org
//wechat:flysnow_org

func callers() *stack {
    const depth = 32
    var pcs [depth]uintptr
    n := runtime.Callers(3, pcs[:])
    var st stack = pcs[0:n]
    return &st
}

func New(text string) error {
    return &errorString{
        s:   text,
        stack: callers(),
    }
}

完美解决,现在如果再解决,对现有的错误附加一些信息的问题呢?相信大家应该有思路了。

type withMessage struct {
    cause error
    msg   string
}

func WithMessage(err error, message string) error {
    if err == nil {
        return nil
    }
    return &withMessage{
        cause: err,
        msg:   message,
    }
}
WithMessageerror

推荐的方案

github.com/pkg/errors
github.com/pkg/errors
New
func New(message string) error
error
//只附加新的信息
func WithMessage(err error, message string) error

//只附加调用堆栈信息
func WithStack(err error) error

//同时附加堆栈和信息
func Wrap(err error, message string) error
errorCauseCauseCause
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
}
forerror
Formatterfmt.Printf
%s,%v //功能一样,输出错误信息,不包含堆栈
%q //输出的错误信息带引号,不包含堆栈
%+v //输出错误信息和堆栈

以上如果有循环包装错误类型的话,会递归的把这些错误都会输出。

小结

github.com/pkg/errors
Log
errors
flysnow_org