虽然在很多关于go panic的文章里不推荐使用panic-recover处理业务异常,原因可能是在go早期,很少应用到业务系统中。
在业务系统中,错误码-错误信息是很重要的一部分。
如果使用err,一般会从问题现场return一直到业务入口处,如果层级特别深,则会造成比较大的成本,代码也会变得不够清晰。
使用panic则会规避以上情况,并且可以在业务入口处做到统一处理,简单直接规范错误码。
gin使用方式
实现`gin.HandlerFunc`, 并注册到gin里,如
func Recover() gin.HandlerFunc {
return func(c *gin.Context) {
defer func() {
if r := recover(); r != nil {
c.JSON(http.StatusOK, util.Struct2Map(r))
}
}()
c.Next()
}
}
r := gin.Default()
r.Use(Recover())
Go gRPC进阶-go-grpc-middleware使用
go-grpc-middleware封装了认证(auth), 日志( logging), 消息(message), 验证(validation), 重试(retries) 和监控(retries)等拦截器。
我们可以根据此扩展点处理所有的panic
var recoverHandler = func(next http.Handler) http.Handler {
return http.HandlerFunc(
func(w http.ResponseWriter, req *http.Request) {
defer func() {
if err := recover(); err != nil {
if resultVO, ok := err.(vo.ResultVO); ok {
body := &resultVO
handleResultVO(w, body)
} else {
body := &vo.ResultVO{
Errno: 500,
Errmsg: util.Iface2string(err),
}
handleResultVO(w, body)
}
}
}()
next.ServeHTTP(w, req)
},
)
}
注册使用此recoverHandler
srv.AddHTTPMiddleware(recoverHandler)
另外,err通用处理也可以使用此方式
func errorHandler(ctx context.Context, mux *runtime.ServeMux, marshaler runtime.Marshaler, w http.ResponseWriter, r *http.Request, err error) {
body := &vo.ResultVO{
Errno: 500,
Errmsg: err.Error(),
}
handleResultVO(w, body)
}
文章来源于互联网:全局异常处理之Golang(error/panic)