Go gin框架處理panic的方法詳解
本文我們介紹下recover在gin框架中的應用。 首先,在golang中,如果在子協(xié)程中遇到了panic,那么主協(xié)程也會被終止。如下:
package main
import (
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
// 在子協(xié)程中引起panic,主協(xié)程也會退出
go func() {
panic("hello world")
}()
// Listen and Server in 0.0.0.0:8080
r.Run(":8080")
}panic被描述為不可處理的錯誤。在web服務中就是服務會崩潰。當然,這在生產環(huán)境下是不可接受的。那么,如何能夠做到發(fā)生panic時技能捕獲該panic又能讓服務繼續(xù)健康運行呢?
這就是golang中提供的recover函數了。recover函數能夠捕獲Panic錯誤并恢復程序的正常運行。
接下來,我們看下recover函數在gin框架中是如何應用的。
首先,要提到的就是gin框架中的recovery中間件。在gin中,是通過使用該中間件來捕獲panic,并保證服務不down機的。 如果使用gin.Default()函數進行構建gin對象,那么默認就注冊了Recovery中間件。
func Default() *Engine {
debugPrintWARNINGDefault()
engine := New()
// 注冊了Recovery中間件
engine.Use(Logger(), Recovery())
return engine
}其次,我們來看下Recovery()中間件都做了些什么。
Recovery()函數定義如下:
func Recovery() HandlerFunc {
return RecoveryWithWriter(DefaultErrorWriter)
}這里的DefaultErrorWriter是默認的輸出端,即os.Stderr。即指錯誤的輸出到什么地方。
接下來看RecoveryWithWriter函數中的實現
// RecoveryWithWriter returns a middleware for a given writer that recovers from any panics and writes a 500 if there was one.
func RecoveryWithWriter(out io.Writer, recovery ...RecoveryFunc) HandlerFunc {
if len(recovery) > 0 {
return CustomRecoveryWithWriter(out, recovery[0])
}
return CustomRecoveryWithWriter(out, defaultHandleRecovery)
}這里有一個參數是defaultHandleRecovery,我們看下它的實現:
func defaultHandleRecovery(c *Context, err any) {
c.AbortWithStatus(http.StatusInternalServerError)
}就是寫入了一個代表內部服務器錯誤的狀態(tài)碼500,并結束了本次請求。
這里關鍵點是CustomRecoveryWithWriter的實現,代碼很長,我們分段來看。如下:

主要分三部分:
將日志輸出到out中,這里是上述提到的DefaultErrorWriter,即os.Stderr。
defer延遲執(zhí)行部分。
c.Next()正常請求處理器部分。
這里需要注意的點就是:
recover函數需要再defer中調用。因為defer是在函數返回時才調用,所以當發(fā)生panic時會導致函數返回,這樣才能捕獲panic。
作為中間件運行,說明每次請求的處理器都被中間件包裝了,也就相當于每個請求處理器都有這個defer函數。
在defer函數中,如果捕獲了panic,則將panic的詳細詳細記錄下來,可以發(fā)送到指定的輸出中,即函數中指定的out參數(默認是os.Stderr),也可以指定其他的文件或Sentry等。
在gin中,正是該中間件的應用,確保了web服務的健壯性。當然,其他的web框架也有同樣的機制,實現原理也是一樣的。
以上就是Go gin框架處理panic的方法詳解的詳細內容,更多關于Go gin框架處理panic的資料請關注腳本之家其它相關文章!
相關文章
Golang使用gin模板渲染base64圖片出現#ZgotmplZ的解決辦法
這篇文章主要介紹了Golang使用gin模板渲染base64圖片出現#ZgotmplZ的的場景復現和解決辦法,文中通過代碼示例講解的非常詳細,對大家解決問題有一定的幫助,需要的朋友可以參考下2024-05-05

