统一错误拦截中间件通过defer+recover捕获panic并返回标准JSON错误响应,支持Gin、Echo、Chi及原生net/http框架,可结合AppError类型实现主动错误传递与统一处理。

在 Golang Web 开发中,统一错误拦截中间件用于捕获处理程序中未被处理的 panic 或自定义错误,避免服务崩溃并返回一致的错误响应格式。无论是使用 Gin、Echo、Chi 还是原生 net/http,都可以通过中间件机制实现这一目标。
HTTP 中间件本质是一个函数,接收一个 http.HandlerFunc 并返回一个新的 http.HandlerFunc。它可以在请求进入实际处理逻辑前或后执行额外操作,比如日志记录、身份验证和错误恢复。
关键点在于使用 defer 和 recover() 捕获 panic,防止其向上蔓延导致程序终止。
func ErrorMiddleware(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// 使用 defer + recover 捕获 panic
defer func() {
if err := recover(); err != nil {
// 记录堆栈信息(可选)
log.Printf("Panic recovered: %v\n", err)
debug.PrintStack()
// 返回统一错误响应
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusInternalServerError)
json.NewEncoder(w).Encode(map[string]string{
"error": "Internal server error",
})
}
}()
// 调用下一个处理器,可能触发 panic
next(w, r)
}
}不同框架注册中间件的方式略有差异,但核心逻辑一致。
立即学习“go语言免费学习笔记(深入)”;
Gin 框架func ErrorHandler() gin.HandlerFunc {
return func(c *gin.Context) {
defer func() {
if err := recover(); err != nil {
log.Printf("Panic: %v", err)
c.JSON(500, gin.H{"error": "Internal server error"})
c.Abort()
}
}()
c.Next()
}
}
// 使用
r := gin.Default()
r.Use(ErrorHandler())
r.GET("/test", func(c *gin.Context) {
panic("something went wrong")
})e := echo.New()
e.Use(func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
defer func() {
if r := recover(); r != nil {
log.Printf("Panic: %v", r)
c.JSON(500, map[string]string{"error": "Internal server error"})
}
}()
return next(c)
}
})r := chi.NewRouter()
r.Use(ErrorMiddleware) // 使用前面定义的通用中间件
r.Get("/", func(w http.ResponseWriter, r *http.Request) {
panic("oops")
})建议定义标准错误格式,便于前端解析和日志分析。
type ErrorResponse struct {
Code int `json:"code"`
Message string `json:"message"`
Detail string `json:"detail,omitempty"` // 可选详细信息(开发环境)
}
func sendError(w http.ResponseWriter, code int, message, detail string) {
resp := ErrorResponse{
Code: code,
Message: message,
}
if env == "dev" { // 根据环境决定是否暴露细节
resp.Detail = detail
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(code)
json.NewEncoder(w).Encode(resp)
}在中间件中调用:sendError(w, 500, "Internal error", fmt.Sprintf("%v", err))
除了捕获 panic,还可设计应用级错误,通过 context 或返回值传递,在中间件中统一处理。
例如:
AppError{Code, Message, Status}
AppError 并序列化输出这样既能控制流程,又能保证异常不遗漏。
基本上就这些。统一错误拦截的核心是利用 defer+recover 构建保护层,结合框架中间件机制注入到请求生命周期中。只要结构清晰,就能在任何 Go Web 项目中快速落地。
以上就是如何实现Golang统一错误拦截中间件_Golang Web框架通用做法的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号