Go-Gin全局错误处理中间件

为了防止报错引起Gin服务挂掉以及错误日志记录,我们使用全局错误中间件进行管理。

go 复制代码
package middleware

import (
	"ToDoList/global"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
	"net"
	"net/http"
	"net/http/httputil"
	"os"
	"runtime/debug"
	"strings"
)

// GinRecovery recover掉项目可能出现的panic,并使用zap记录相关日志
func GinRecovery(stack bool) gin.HandlerFunc {
	return func(c *gin.Context) {
		defer func() {
			if err := recover(); err != nil {
				var brokenPipe bool
				// 如果是连接错误并且错误信息中包含"broken pipe"或"connection reset by peer",则认为是客户端断开连接导致的错误。
				if ne, ok := err.(*net.OpError); ok {
					if se, ok := ne.Err.(*os.SyscallError); ok {
						if strings.Contains(strings.ToLower(se.Error()), "broken pipe") || strings.Contains(strings.ToLower(se.Error()), "connection reset by peer") {
							brokenPipe = true
						}
					}
				}
				//如果brokenPipe为true,表明客户端断开连接导致的错误,则使用zap记录相关日志,并将错误信息作为错误返回给客户端。
				httpRequest, _ := httputil.DumpRequest(c.Request, false)
				if brokenPipe {
					global.GVA_LOG.Error(c.Request.URL.Path,
						zap.Any("error", err),
						zap.String("request", string(httpRequest)),
					)

					_ = c.Error(err.(error))
					c.Abort()
					return
				}
				//如果stack为true,则使用debug.Stack()函数获取堆栈信息,并使用zap记录相关日志。
				if stack {
					global.GVA_LOG.Error("[Recovery from panic]",
						zap.Any("error", err),
						zap.String("request", string(httpRequest)),
						zap.String("stack", string(debug.Stack())),
					)
				} else {
					global.GVA_LOG.Error("[Recovery from panic]",
						zap.Any("error", err),
						zap.String("request", string(httpRequest)),
					)
				}
				//发生错误中止当前请求并返回500状态码。
				c.AbortWithStatus(http.StatusInternalServerError)
			}
		}()
		c.Next()
	}
}
相关推荐
Q_Q51100828529 分钟前
python题库及试卷管理系统
开发语言·spring boot·python·django·flask·node.js·php
电商API_180079052471 小时前
淘宝天猫商品数据爬取方案:官方API与非官方接口对比
linux·服务器·开发语言·前端·爬虫·python·数据挖掘
mxpan1 小时前
golang 一种并发安全 map 的实现
开发语言·golang
漫无目的行走的月亮1 小时前
微信小程序,微信授权手机号码
开发语言·javascript·ecmascript
我命由我123451 小时前
Android 开发问题:CardView 的阴影效果会受到父容器的裁切
android·java·开发语言·java-ee·android studio·android-studio·android runtime
追风赶月、2 小时前
【QT】控件二(输入类控件、多元素控件、容器类控件与布局管理器)
开发语言·qt
API_technology2 小时前
亚马逊 API 实战:商品详情页实时数据采集接口开发与调用
大数据·开发语言·python·数据挖掘
vhgcc2 小时前
在 Java 中使用 Apache Tika 读取 doc、docx等格式文件内容
java·开发语言·自然语言处理·apache·ai编程
YuTaoShao5 小时前
Java八股文——MySQL「锁篇」
java·开发语言·mysql
全干engineer1 天前
Web3-Web3.js核心操作:Metamask、合约调用、事件订阅全指南
开发语言·javascript·web3·区块链·智能合约