错误(error)
type error interface {
Error() string
}
- 自定义错误值应该统一分组定义,而不是零散的分布在各个角落
var (
ErrEof = errors.New("EOF")
ErrClosedPipe = errors.New("io: read/write on closed pipe")
)
f() {
if err := ff(); err != nil {
return fmt.Errorf("f: %w", err)
}
}
err = errors.Unwrap(err)
func logPanics(f http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
defer func() {
if err := recover(); err != nil {
log.Printf("[%v] caught panic: %v", r.RemoteAddr, err)
}
f(w, r)
}()
}
}
http.HandleFunc("/<path>", logPanics(func1))
异常(panic)
- 异常的恢复(recover)必须写在defer函数中
- 一个子goroutine中发生panic会导致整个程序崩溃
- 一个goroutine发生的异常只能被自己恢复
- 每一个可能panic的goroutine都要加上异常恢复处理
- panic表示发生了严重的错误,不应该被频繁使用
- 但有时可以通过panic简化错误处理
func first() error {return nil}
func second() error {return nil}
func third() error {return nil}
func Do() error {
var err error
if err = first(); err == nil {
if err = second(); err == nil {
if err = third(); err == nil {
return nil
}
}
}
return err
}
func Do2() (err error) {
defer func(){
if r:= recover() ; r!= nil{
err = fmt.Errorf("Error: %+v", r)
}
}()
first2()
second2()
third2()
return
}
- recover只有在defer中才会生效,且defer必须注册在panic前
- 如果要在上层函数捕获下层函数的panic,则defer必须在下层函数调用前注册(定义)
func f() {
defer func() {
if err := recover(); err != nil {
fmt.Println(err)
}
}()
ff()
}
func ff() {
panic("panic in ff")
}