// New returns an error that formats as the given text. // Each call to New returns a distinct error value even if the text is identical. funcNew(text string)error { return &errorString{text} }
// errorString is a trivial implementation of error. type errorString struct { s string }
// EOF is the error returned by Read when no more input is available. // Functions should return EOF only to signal a graceful end of input. // If the EOF occurs unexpectedly in a structured data stream, // the appropriate error is either ErrUnexpectedEOF or some other error // giving more detail. var EOF = errors.New("EOF")
// ErrUnexpectedEOF means that EOF was encountered in the // middle of reading a fixed-size block or data structure. var ErrUnexpectedEOF = errors.New("unexpected EOF")
// ErrNoProgress is returned by some clients of an io.Reader when // many calls to Read have failed to return any data or error, // usually the sign of a broken io.Reader implementation. var ErrNoProgress = errors.New("multiple Read calls return no data or error")
我们在外部判定的时候一般使用等值判定或者使用 errors.Is 进行判断
1 2 3 4 5 6 7
if err == io.EOF { //... }
if errors.Is(err, io.EOF){ //... }
这种错误处理方式有一个问题是,将 error 当做包的 API 暴露给了第三方,这样会导致在做重构或者升级的时候很麻烦,并且这种方式包含的错误信息会十分的有限
// Wrap returns an error annotating err with a stack trace // at the point Wrap is called, and the supplied message. // If err is nil, Wrap returns nil. funcWrap(err error, message string)error { if err == nil { returnnil } err = &withMessage{ cause: err, msg: message, } return &withStack{ err, callers(), } }
funcAs(err error, target interface{})bool { if target == nil { panic("errors: target cannot be nil") } val := reflectlite.ValueOf(target) typ := val.Type() if typ.Kind() != reflectlite.Ptr || val.IsNil() { panic("errors: target must be a non-nil pointer") } if e := typ.Elem(); e.Kind() != reflectlite.Interface && !e.Implements(errorType) { panic("errors: *target must be interface or implement error") } targetType := typ.Elem() for err != nil { if reflectlite.TypeOf(err).AssignableTo(targetType) { val.Elem().Set(reflectlite.ValueOf(err)) returntrue } if x, ok := err.(interface{ As(interface{}) bool }); ok && x.As(target) { returntrue } err = Unwrap(err) } returnfalse }
// New returns an error that formats as the given text. // Each call to New returns a distinct error value even if the text is identical. funcNew(text string)error { return &errorString{text} }
// errorString is a trivial implementation of error. type errorString struct { s string }
// EOF is the error returned by Read when no more input is available. // Functions should return EOF only to signal a graceful end of input. // If the EOF occurs unexpectedly in a structured data stream, // the appropriate error is either ErrUnexpectedEOF or some other error // giving more detail. var EOF = errors.New("EOF")
// ErrUnexpectedEOF means that EOF was encountered in the // middle of reading a fixed-size block or data structure. var ErrUnexpectedEOF = errors.New("unexpected EOF")
// ErrNoProgress is returned by some clients of an io.Reader when // many calls to Read have failed to return any data or error, // usually the sign of a broken io.Reader implementation. var ErrNoProgress = errors.New("multiple Read calls return no data or error")
我们在外部判定的时候一般使用等值判定或者使用 errors.Is 进行判断
1 2 3 4 5 6 7
if err == io.EOF { //... }
if errors.Is(err, io.EOF){ //... }
这种错误处理方式有一个问题是,将 error 当做包的 API 暴露给了第三方,这样会导致在做重构或者升级的时候很麻烦,并且这种方式包含的错误信息会十分的有限
// Wrap returns an error annotating err with a stack trace // at the point Wrap is called, and the supplied message. // If err is nil, Wrap returns nil. funcWrap(err error, message string)error { if err == nil { returnnil } err = &withMessage{ cause: err, msg: message, } return &withStack{ err, callers(), } }
funcAs(err error, target interface{})bool { if target == nil { panic("errors: target cannot be nil") } val := reflectlite.ValueOf(target) typ := val.Type() if typ.Kind() != reflectlite.Ptr || val.IsNil() { panic("errors: target must be a non-nil pointer") } if e := typ.Elem(); e.Kind() != reflectlite.Interface && !e.Implements(errorType) { panic("errors: *target must be interface or implement error") } targetType := typ.Elem() for err != nil { if reflectlite.TypeOf(err).AssignableTo(targetType) { val.Elem().Set(reflectlite.ValueOf(err)) returntrue } if x, ok := err.(interface{ As(interface{}) bool }); ok && x.As(target) { returntrue } err = Unwrap(err) } returnfalse }