Golang如何优雅处理错误

258 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第7天,点击查看活动详情

go语言中函数返回基本结构response,error模式,作为开发者如何应对各种场景错误和捕捉异常panic成为日常必不可少工作。 首先go里没有java中try-catch-finally这种异常捕捉机制,替代捕捉异常/关闭资源的是defer语句。所以日常需要捕捉异常处理函数,几乎每个项目都必不可少:

func CheckPanic() {
   if err := recover(); err != nil {
      // what to do when panic
      ```
    TracePanicStack(err)
   }
}

func YourFuction() (response,error) {
   defer check_panic.CheckPanic()
   // your logic function
}

有趣的是,golang里error是个接口,而不是类型,这意味着你可以通过实现error接口自定义错误类型

type error interface {
 Error() string
}

type MyError struct {
   Code    int    `json:"code"`
   Message string `json:"message"`
}

func (t *MyError) Error() string {
   return t.String()
}

switch err.(type) {
    case *MyError:
     // what to do when error type is my error
    default: 
        // unknown error
}

错误通常如何包装和嵌套?

if err != nil { 
            return fmt.Errorf("something failed: %v", err)
}

fmt.Sprintf("authorization failed during %s: %v", “infomation”, err)}

更进阶些:
import "github.com/pkg/errors"
if err != nil { 
    return errors.Wrap(err, "something failed")
}
// Cause接口switch 
err := errors.Cause(err).(type) {
    case *MyError: 
    // handle specifically
    default: 
    // unknown error
}

如何应对头疼的error check?

err := dosomething(1)
if err != nil {
// resp to do 1
   return err
}

err=dosomething(2)
if err != nil {
// resp to do 2
   return err
}

err=dosomething(3)
if err != nil {
// resp to do 3
   return err
}

凡是发现重复的模式出现,都是可以简化的地方,下一期再讲如何优化。