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