Golang web项目的全局错误处理

Echo framework写法示例
 	// 创建 Echo 实例
	e := echo.New()

	// Custom error handler
	e.HTTPErrorHandler = func(err error, c echo.Context) {
		// Log the error
		log.Logger.Error("ErrorRequest: ", zap.Error(err))

		// Prepare the error response
		code := http.StatusInternalServerError
		// he指针
		var he *echo.HTTPError
		// errors.As函数会尝试将err转为echo.HTTPError类型对象,若成功,则he即指向该对象
		if errors.As(err, &he) {
			// 将err转换为echo.HTTPError类成功后,将其Code字段值赋给上面声明的code变量(默认值500)
			code = he.Code
			// TODO 可以在此处对code值进行策略模式的处理
		}

		// Send the error response
		if !c.Response().Committed {
			if c.Request().Method == http.MethodHead {
				// // 如果请求方法是HEAD,则发送一个没有内容的响应。
				err = c.NoContent(code)
			} else {
				err = c.JSON(code, map[string]string{"error": err.Error()})
			}
			if err != nil {
				log.Logger.Error("Failed to send error response: ", zap.Error(err))
			}
		}
	}

 

Gin framework写法示例
 func main() {

	r := gin.New()

	// 使用中间件来处理错误
	r.Use(gin.RecoveryWithWriter(gin.DefaultErrorWriter))

	// 注册全局错误处理中间件
	r.Use(errorHandler)

	// 依赖注入
	helloHandler := utils.DIHelloHandler()
	// ... 其他路由设置 ...
	r.GET("/error", helloHandler.ErrorRequest)

	// 运行Gin服务
	r.Run(":8000")
}

// errorHandler 是一个中间件,用于捕获和处理错误
func errorHandler(c *gin.Context) {
	c.Next()

	if len(c.Errors) > 0 {
		lastErr := c.Errors.Last()

		// 如果 Meta 是 int(状态码)
		if statusCode, ok := lastErr.Meta.(int); ok {
			// TODO 可以在此处对code值进行策略模式的处理,记录日志,触发警告……等行为
			c.AbortWithStatusJSON(statusCode, gin.H{
				"error": lastErr.Error(),
			})
			return
		}
		// 没有状态码,默认 500
		c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{
			"error": lastErr.Error(),
		})
	}
}

func (h HelloHandler) ErrorRequest(context *gin.Context) {
	_ = context.Error(fmt.Errorf("custom error")).SetType(gin.ErrorTypeAny).SetMeta(http.StatusTooManyRequests)
}
posted @ 2025-04-03 21:34  Ashe|||^_^  阅读(17)  评论(0)    收藏  举报