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

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

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()
	}
}

相关推荐

  1. Go-Gin全局错误处理中间

    2024-04-02 11:52:03       33 阅读
  2. go-zero 全局异常处理-全局中间

    2024-04-02 11:52:03       46 阅读
  3. Go 错误处理

    2024-04-02 11:52:03       65 阅读
  4. Go 处理错误&异常

    2024-04-02 11:52:03       37 阅读
  5. Go 错误处理

    2024-04-02 11:52:03       25 阅读
  6. go gin中间关于 c.next()、c.abort()和return的使用

    2024-04-02 11:52:03       49 阅读
  7. gin自定义中间

    2024-04-02 11:52:03       29 阅读
  8. 中间 | Redis - [全局 hash & 渐进 rehash]

    2024-04-02 11:52:03       41 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-02 11:52:03       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-02 11:52:03       100 阅读
  3. 在Django里面运行非项目文件

    2024-04-02 11:52:03       82 阅读
  4. Python语言-面向对象

    2024-04-02 11:52:03       91 阅读

热门阅读

  1. C++ TCP 服务端和客户端通信的例子

    2024-04-02 11:52:03       35 阅读
  2. 前端 prefetch 和 preload 的区别?

    2024-04-02 11:52:03       39 阅读
  3. Yarn 包管理器入门指南

    2024-04-02 11:52:03       36 阅读
  4. linux定时调度任务

    2024-04-02 11:52:03       34 阅读
  5. Hadoop系列总结

    2024-04-02 11:52:03       41 阅读
  6. openGL创建平面、立方体、圆柱体、斜面和棱柱Demo

    2024-04-02 11:52:03       39 阅读
  7. redis-Hash

    2024-04-02 11:52:03       39 阅读
  8. 【Vmware】 debian 12 安装教程

    2024-04-02 11:52:03       42 阅读
  9. C 练习实例96 - 字符串中的子串

    2024-04-02 11:52:03       36 阅读