社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
Recovery返回一个中间件,该中间件从任何恐慌中恢复,并写入500(如果有)。当你的程序出现一些你未考虑到的异常时,程序就会退出,服务就停止了,所以这个中间件是有必要的。
// Recovery returns a middleware that recovers from any panics and writes a 500 if there was one.
func Recovery() HandlerFunc {
return RecoveryWithWriter(DefaultErrorWriter)
}
我们都知道golang中painc时,会造成崩溃退出。而gin.Recocery()会返回http code 500。但是若连接断开则不会返回http code
if brokenPipe {
// If the connection is dead, we can't write a status to it.
c.Error(err.(error)) // nolint: errcheck
c.Abort()
} else {
handle(c, err)
}
当使用gin.Default()的时候,会默认启用gin.Recocery()这个中间件。而使用gin.New()则需要自己添加
这里顺带提一下gin.Default()和gin.New()
不同点:
gin.Default()返回一个已连接记录器和恢复中间件的引擎实例,即Logger 和 Recovery 中间件,我们在这里可以看到gin.Default本质上就是调用了gin.New,然后再Use Logger 和 Recovery这两个中间件
// Default returns an Engine instance with the Logger and Recovery middleware already attached.
func Default() *Engine {
debugPrintWARNINGDefault()
engine := New()
engine.Use(Logger(), Recovery())
return engine
}
gin.New()返回一个新的空引擎实例,不附加任何中间件
// New returns a new blank Engine instance without any middleware attached.
// By default, the configuration is:
// - RedirectTrailingSlash: true
// - RedirectFixedPath: false
// - HandleMethodNotAllowed: false
// - ForwardedByClientIP: true
// - UseRawPath: false
// - UnescapePathValues: true
func New() *Engine {
debugPrintWARNINGNew()
engine := &Engine{
RouterGroup: RouterGroup{
Handlers: nil,
basePath: "/",
root: true,
},
FuncMap: template.FuncMap{},
RedirectTrailingSlash: true,
RedirectFixedPath: false,
HandleMethodNotAllowed: false,
ForwardedByClientIP: true,
RemoteIPHeaders: []string{"X-Forwarded-For", "X-Real-IP"},
TrustedPlatform: defaultPlatform,
UseRawPath: false,
RemoveExtraSlash: false,
UnescapePathValues: true,
MaxMultipartMemory: defaultMultipartMemory,
trees: make(methodTrees, 0, 9),
delims: render.Delims{Left: "{{", Right: "}}"},
secureJSONPrefix: "while(1);",
trustedProxies: []string{"0.0.0.0/0", "::/0"},
trustedCIDRs: defaultTrustedCIDRs,
}
engine.RouterGroup.engine = engine
engine.pool.New = func() any {
return engine.allocateContext()
}
return engine
}
二者的相同点:gin.New()和gin.Default()都是初始化一个Engine 实例
可能有些人会疑惑,既然有gin.Default为什么要用gin.New呢,正如上面所言,由于gin.New没有Logger中间件,那么我们可以根据自己的需求定义自己的日志中间件,而不用自带的,一般在项目中我们都用的自己定义的日志中间件,到时候只需要用Use(中间件名字),即可引入,Default的源码就是这样整的
gin 还提供额外的Recovery中间件,CustomRecovery和RecoveryWithWriter
Recovery()是另外俩个的封装,如果额外扩张,自定义ioWriter 或者handle可以用RecoveryWithWriter
注意:gin的recover中间件只是对主进程的异常进行捕获,如果要想处理协程里面的panic 单独的recover,可以参考https://taoshu.in/go/safe-goroutine.html
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!