Golang實現(xiàn)自定義recovery中間件
為什么需要實現(xiàn)自定義 recovery 中間件
在 Golang 的 Web 項目中,自定義 recovery 中間件是一種常見的做法,用于捕獲并處理應(yīng)用程序的運(yùn)行時錯誤,以避免整個應(yīng)用程序崩潰并返回對應(yīng)格式的響應(yīng)數(shù)據(jù)。
很多三方 web 框架(例如 gin、echo)都提供了官方實現(xiàn)的 recovery 中間件,但是官方實現(xiàn)的中間件并不一定能滿足自己的需求。例如 gin 官方提供的 recovery 中間件,發(fā)生 panic 后會將當(dāng)前請求的標(biāo)準(zhǔn)狀態(tài)碼置為 500,body 置為空。但是這樣的返回數(shù)據(jù)與格式可能會和自己的項目要求不一致。例如,項目發(fā)生 panic 后是要求標(biāo)準(zhǔn)狀態(tài)碼依然返回 200,body 值為 {"code":-1, "data":nil,"msg":"xxx"},這種場景下,就需要實現(xiàn)自己的 recovery 中間件了。
如何實現(xiàn)自定義 recovery 中間件
如果使用 gin 框架的話,就非常簡單了,因為 gin 提供了完善的中間件功能,遵守 gin 的要求實現(xiàn)滿足自己項目的功能就可以了,簡單示例代碼如下:
package main
import (
"github.com/gin-gonic/gin"
"log"
"net/http"
"runtime"
)
func Recovery() gin.HandlerFunc {
return func(c *gin.Context) {
defer func() {
if err := recover(); err != nil {
const size = 64 << 10
stack := make([]byte, size)
stack = stack[:runtime.Stack(stack, false)]
log.Printf("[GinPanic] %s\n", string(stack))
c.JSON(http.StatusOK, struct {
Code int `json:"code"`
Data interface{} `json:"data"`
Msg string `json:"msg"`
}{
Code: -1,
Data: nil,
Msg: "server panic",
})
c.Abort()
}
}()
c.Next()
}
}使用示例如下:
package main
import (
"github.com/gin-gonic/gin"
"runtime"
)
func main() {
r := gin.New()
r.Use(Recovery())
r.GET("/test", func(c *gin.Context) {
panic("Oops! Something went wrong.")
})
r.Run(":8080")
}運(yùn)行起來后,訪問 /test 觸發(fā) panic 后返回了預(yù)期的結(jié)果,如下:
$ curl http://127.0.0.1:8080/test
{"code":-1,"data":null,"msg":"server panic"}
接下來再看一個基于原生包 net/http 的一個示例,代碼如下:
package main
import (
"fmt"
"log"
"net/http"
"runtime/debug"
)
// 自定義的recovery中間件
func recoveryMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer func() {
if err := recover(); err != nil {
// 打印錯誤信息
log.Println("[Recovery] Panic:", err)
// 打印堆棧跟蹤信息
log.Printf("[Recovery] Stack Trace:\n%s\n", debug.Stack())
// 返回一個適當(dāng)?shù)腻e誤響應(yīng)給客戶端
fmt.Fprintf(w, `{"code":-1,"data":null,"msg":"server panic"}`)
}
}()
// 繼續(xù)處理下一個中間件或路由處理函數(shù)
next.ServeHTTP(w, r)
})
}
// 示例的處理函數(shù)
func helloHandler(w http.ResponseWriter, r *http.Request) {
panic("Oops! Something went wrong.") // 模擬一個錯誤
w.Write([]byte("Hello, Recovery Middleware!"))
}
func main() {
// 創(chuàng)建一個多路復(fù)用器
mux := http.NewServeMux()
// 注冊中間件
mux.Handle("/test", recoveryMiddleware(http.HandlerFunc(helloHandler)))
// 創(chuàng)建服務(wù)器
server := &http.Server{
Addr: ":8080",
Handler: mux,
}
// 啟動服務(wù)器
log.Println("Server is running on http://localhost:8080")
log.Fatal(server.ListenAndServe())
}小結(jié)
Web 應(yīng)用程序在運(yùn)行時遇到錯誤并拋出 panic 時,自定義的 recovery 中間件將會捕獲panic 并記錄對應(yīng)的錯誤和堆棧信息,避免應(yīng)用程序崩潰,并向客戶端發(fā)送適當(dāng)?shù)腻e誤響應(yīng)數(shù)據(jù)。對于文本的示例,可以根據(jù)自己的實際需求進(jìn)行調(diào)整和擴(kuò)展來實現(xiàn)自定義的 recovery 中間件。
到此這篇關(guān)于Golang實現(xiàn)自定義recovery中間件的文章就介紹到這了,更多相關(guān)go recovery內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Golang Map value不可尋址使用指針類型代替示例詳解
這篇文章主要為大家介紹了Golang Map value不可尋址使用指針類型代替示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11
Golang10進(jìn)制轉(zhuǎn)16進(jìn)制的幾種方法代碼示例
這篇文章主要給大家介紹了關(guān)于Golang10進(jìn)制轉(zhuǎn)16進(jìn)制的幾種方法,進(jìn)制轉(zhuǎn)換是Golang的一些基本操作,文中通過實例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-07-07
深入了解Golang網(wǎng)絡(luò)編程N(yùn)et包的使用
net包主要是增加?context?控制,封裝了一些不同的連接類型以及DNS?查找等等,同時在有需要的地方引入?goroutine?提高處理效率。本文主要和大家分享下在Go中網(wǎng)絡(luò)編程的實現(xiàn),需要的可以參考一下2022-07-07

