Golang實現(xiàn)自定義recovery中間件
為什么需要實現(xiàn)自定義 recovery 中間件
在 Golang 的 Web 項目中,自定義 recovery 中間件是一種常見的做法,用于捕獲并處理應用程序的運行時錯誤,以避免整個應用程序崩潰并返回對應格式的響應數(shù)據(jù)。
很多三方 web 框架(例如 gin、echo)都提供了官方實現(xiàn)的 recovery 中間件,但是官方實現(xiàn)的中間件并不一定能滿足自己的需求。例如 gin 官方提供的 recovery 中間件,發(fā)生 panic 后會將當前請求的標準狀態(tài)碼置為 500,body 置為空。但是這樣的返回數(shù)據(jù)與格式可能會和自己的項目要求不一致。例如,項目發(fā)生 panic 后是要求標準狀態(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")
}運行起來后,訪問 /test 觸發(fā) panic 后返回了預期的結果,如下:
$ 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())
// 返回一個適當?shù)腻e誤響應給客戶端
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)建一個多路復用器
mux := http.NewServeMux()
// 注冊中間件
mux.Handle("/test", recoveryMiddleware(http.HandlerFunc(helloHandler)))
// 創(chuàng)建服務器
server := &http.Server{
Addr: ":8080",
Handler: mux,
}
// 啟動服務器
log.Println("Server is running on http://localhost:8080")
log.Fatal(server.ListenAndServe())
}小結
Web 應用程序在運行時遇到錯誤并拋出 panic 時,自定義的 recovery 中間件將會捕獲panic 并記錄對應的錯誤和堆棧信息,避免應用程序崩潰,并向客戶端發(fā)送適當?shù)腻e誤響應數(shù)據(jù)。對于文本的示例,可以根據(jù)自己的實際需求進行調整和擴展來實現(xiàn)自定義的 recovery 中間件。
到此這篇關于Golang實現(xiàn)自定義recovery中間件的文章就介紹到這了,更多相關go recovery內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
golang服務報錯:?write:?broken?pipe的解決方案
在開發(fā)在線客服系統(tǒng)的時候,看到日志里有一些錯誤信息,下面這篇文章主要給大家介紹了關于golang服務報錯:?write:?broken?pipe的解決方案,需要的朋友可以參考下2022-09-09
Golang實現(xiàn)對map的并發(fā)讀寫的方法示例
這篇文章主要介紹了Golang實現(xiàn)對map的并發(fā)讀寫的方法示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-03-03
Go語言之使用pprof工具查找goroutine(協(xié)程)泄漏
這篇文章主要介紹了Go語言之使用pprof工具查找goroutine(協(xié)程)泄漏,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-01-01
go使用errors.Wrapf()代替log.Error()方法示例
這篇文章主要為大家介紹了go使用errors.Wrapf()代替log.Error()的方法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-08-08

