gin框架 自定义404错误页面,自定义500等服务端异常,业务异常,根据不同异常类型显示不同的异常页面方法 整理

news2024/9/20 18:46:10

        在gin框架中,要显示自定义的异常页面,首先需要通过gin路由对象中的LoadHTMLFiles或者LoadHTMLGlob方法加载自定义的错误页面模板文件, 然后定义符合 gin.HandlerFunc 类型的路由处理函数/方法 ,即只有一个参数(c *ginx.XContext)的函数或者方法。 404异常使用路由对象的.NoRoute方法绑定路由处理函数, 其他类型的异常采用在中间件中采用defer + recover()函数捕获异常,然后根据不同类型的异常显示不同的模板页面信息。

gin框架中自定义404错误页面

        gin框架中自定义404错误页面, 实际上就是没有路由匹配的页面,使用gin内置的路由对象中的方法 r.NoRoute(Xxx), 这里的r是r := gin.Default() 的对象。 Xxx 就是一个 HandlerFunc 函数类型定义,即函数/方法的参数定义是 func(*Context) ,如: func ErrHandler404(c *ginx.XContext) { }

自定义404错误页面示例:

html模板页面 templates/errors/404.html

{{define "errors/404.html"}}
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{{.title}}</title>
</head>

<body>
    <h1>{{.title}}</h1>
</body>

</html>
{{end}}

 404异常页面HandlerFunc处理函数

// 自定义404异常页面处理器函数
func ErrHandler404(c *gin.Context) {
	c.HTML(200, "errors/404.html", ginx.H{"title": "404 Error - Page not found"})
}

404异常模板文件加载和路由绑定


func main() {
	r := gin.Default()
	// 模式匹配方式加载html模板文件
	r.LoadHTMLGlob("templates/**/*.html")
	// 指定模板文件加载
	//r.LoadHTMLFiles("templates/errors/404.html", "templates/errors/500.html")

	// 自定义404异常页面处理路由绑定
	r.NoRoute(ErrHandler404)

	// 路由绑定
	r.GET("/", func(c *gin.Context) {
		c.JSON(http.StatusOK, gin.H{
			"title": "Hello world!",
		})
	})

	r.Run(":8080")
}

启动服务, 访问 http://localhost:8080/abc  这时就会显示我们自定义的404异常页面

gin框架根据不同的异常类型显示不同的异常页面的方法

gin框架根据不同类型的异常显示不同的异常页面采用在中间件中采用defer + recover()函数捕获异常,然后根据不同类型的异常显示不同的模板页面信息。 

这个也是需要先加载模板文件的,方法和上面的一样

html异常模板文件定义

 templates/errors/500.html   其他模板文件定义省略, 注意这里的模板文件名称定义 ,即 {{define "模板文件名"}} 

{{define "errors/500.html"}}
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{{.title}}</title>
</head>

<body>
    <h1>{{.title}}</h1>
    <h2>{{.msg}}</h2>
</body>

</html>
{{end}}

defer + recover()异常处理中间件定义

defer + recover()函数, 然后在使用  switch err := recErr.(type) { case xxx: } 的形式根据不同的异常类型显示不同的html模板和数据。

下面的switch case里面就是我们要捕获的异常类型,  case的类型就是我们通过panic获取其他程序抛出的异类型, 如 panic("Demo Error ") 这个是一个string类型的异常,在case里面就会被string分支捕获;这个异常  panic(&net.OpError{Op: "read",Net: "tcp", Err: fmt.Errorf("demo for op error")}) 就会被 case *net.OpError: 分支捕获。 其他的以此类推.....


// 服务器异常处理中间件
func ErrHandlerMiddleware(c *gin.Context) {
	// 注意这里通过defer语句+recover()函数来捕获异常
	defer func() {
		// 注意这里的recover()返回的异常类型是interface{}类型,可以通过类型断言来判断是何种类型的异常
		if recErr := recover(); recErr != nil {
			tpl := "errors/500.html" // 默认异常模板文件
			data := make(map[string]interface{})
			// switch + type类型推断
			switch err := recErr.(type) {
			case *net.OpError:
				tpl = "errors/net_error.html"
				data["title"] = "net.OpError exception has occurred"
				data["msg"] = fmt.Sprintf("%v", err.Error())
			case *net.AddrError:
				tpl = "errors/net_error.html"
				data["title"] = "net.AddrError exception has occurred"
				data["msg"] = fmt.Sprintf("%v", err.Error())
			case string:
				data["title"] = err
				data["msg"] = err
			default:
				// 模板数据
				data["title"] = err
				data["msg"] = err
			}
			global.Log.Errorf("error: %v", data)
			//debug.PrintStack() //打印错误堆栈信息
			// 显示自定义错误页面
			c.HTML(200, tpl, data)
		}
	}()
	// 继续后续的处理 这个是中间件和 路由处理控制器的重要区别
	c.Next()
}

gin使用示例

这个方式使用的时候只需要在gin路由对象里面通过Use方法加载这个中间件即可,即:

r.Use(ErrHandlerMiddleware)

在控制器中如果有异常发生,就会被我们定义的中间件捕获, 然后我们就可以在中间件中根据不同的类型设置不同的异常模板页面。

控制器抛异常示例


var IndexCtr = cIndex{}

type cIndex struct{}

func (a *cIndex) DemoErr1(c *gin.Context) {
	// 抛一个异常
	panic("This is not implemented for Demo Error purpose.")
}
func (a *cIndex) DemoErr2(c *gin.Context) {
	// 抛一个异常
	panic(fmt.Errorf("fmt error demo2, gin Request: %v", c.Request))
}
func (a *cIndex) DemoErr3(c *gin.Context) {
	// 抛一个异常 *net.AddrError
	panic(&net.OpError{Op: "read",Net: "tcp", Err: fmt.Errorf("demo for op error")})
}
func (a *cIndex) DemoErr4(c *gin.Context) {
	// 抛一个异常 *net.AddrError
	panic(&net.AddrError{Err: "fmt error demo2", Addr: "localhost"})
}

gin路由 HandlerFunc处理函数/方法 和gin中间件的区别

在gin框架中, 路由的处理函数和中间件的参数定义都是一样的,都必须符合HandlerFunc的类型定义,即: type HandlerFunc func(*Context)

他们的区别在于gin中间件中 使用 c.Next() 方法来处理后续的网络请求。 在路由函数和中间件中如果要中断后续的请求,都需要调用 c.Abort() 方法来中断后续的调用链HandlersChain(这个其实就是一个HandlerFunc切片,他的定义是:type HandlersChain []HandlerFunc   ) 的请求。 而如果要中断当前函数的请求,则都需要使用 return语句。

总结: gin框架中的自定义异常页面实际上就是一个路由绑定和异常捕获和异常类型断言的过程,其中404异常他就是一个无路由异常,需要使用路由对象的 NoRoute方法绑定对应的异常处理函数, 其他类型的异常需要使用 中间件 +defer + recover()的方式来处理不同类型的异常。 在gin 框架中还有一个 NoMethod的路由异常,这个异常在 Engine.HandleMethodNotAllowed = true时触发,使用方法和NoRoute一样,绑定一个HandlerFunc函数即可。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1990830.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何理解供应链控制塔?详解供应链控制塔类型与架构!

随着经济全球化的不断深入&#xff0c;企业供应链的复杂性也在不断增加。从供应商到制造商&#xff0c;再到分销商和消费者&#xff0c;全球供应链网络的每一个环节都充满了动态变化和不确定性。在这样的背景下&#xff0c;传统的供应链管理模式已难以满足现代企业的需求&#…

Ackites/Killwxapkg

自动化反编译微信小程序&#xff0c;小程序安全评估工具&#xff0c;发现小程序安全问题&#xff0c;自动解密&#xff0c;解包&#xff0c;可还..自动化反编译微信小程序&#xff0c;小程序安全评估工具&#xff0c;发现小程序安全问题&#xff0c;自动解密&#xff0c;解包&a…

【消息队列】kafka如何保证消息不丢失?

&#x1f44f;大家好&#xff01;我是和风coding&#xff0c;希望我的文章能给你带来帮助&#xff01; &#x1f525;如果感觉博主的文章还不错的话&#xff0c;请&#x1f44d;三连支持&#x1f44d;一下博主哦 &#x1f4dd;点击 我的主页 还可以看到和风的其他内容噢&#x…

查看有无XSS漏洞验证

实验环境 操作机&#xff1a;Win10 用户名&#xff1a;wangan 密码&#xff1a;123靶机&#xff1a;Apache PHP实验地址&#xff1a;http://ip/xss/level1.php?nametest 实验原理 构造弹窗的代码提交&#xff0c;浏览器在执行该代码后就会执行弹框的操作&#xff0c;弹框的目…

Python请求API的简明教程

前言 随着微服务流行开来&#xff0c;API正在成为数据获取的主要渠道&#xff0c;我们可以通过Java的HttpClient完成数据请求&#xff0c;当然也可以通过Python工具完成数据请求。 本博将对Python如何请求API进行举例&#xff0c;保你一文掌握。 1. 准备工具 在使用Python请…

Java面试题--JVM大厂篇之针对频繁的Minor GC问题,有哪些优化对象创建与使用的技巧可以分享?

目录 引言&#xff1a; 正文&#xff1a; 1. 了解Minor GC的痛点 2. 使用对象池&#xff08;Object Pool&#xff09; 3. 避免不必要的对象创建 4. 使用StringBuilder替代字符串拼接 5. 合理设置对象的作用域 6. 使用软引用和弱引用 结束语&#xff1a; 引言&#xff…

Python | Leetcode Python题解之第330题按要求补齐数组

题目&#xff1a; 题解&#xff1a; class Solution:def minPatches(self, nums: List[int], n: int) -> int:patches, x 0, 1length, index len(nums), 0while x < n:if index < length and nums[index] < x:x nums[index]index 1else:x << 1patches …

分享一款老软件RealPlayer 16.0.1.18

一款怀旧老软件&#xff0c;功能还算强大测试系统win7/10&#xff0c;win11以上系统自行测试&#xff01;这种老软件非常适合配置低的老电脑&#xff0c;尤其是单位办公电脑。

LVS实战演练

一.LVS简介 LVS&#xff08;Linux Virtual Server&#xff09;是Linux虚拟服务器的简称&#xff0c;是一种基于Linux内核的开源负载均衡技术。 <1>.工作原理 LVS&#xff08;Linux Virtual Server&#xff09;的工作原理可以概括为通过负载均衡技术将客户端的请求分发到…

论文解读 | ACL 2024:自我蒸馏在语言模型微调中架起分布差异的桥梁

点击蓝字 关注我们 AI TIME欢迎每一位AI爱好者的加入&#xff01; 杨兆瑞 浙江大学CAD&CG全国重点实验室博士生 导师为陈为教授 概述 大型语言模型&#xff08;LLMs&#xff09;的兴起彻底改变了自然语言处理领域&#xff0c;但对它们进行特定任务的微调常常面临在平衡性能…

MySQL数据分析进阶(九)触发器

※食用指南&#xff1a;文章内容为‘CodeWithMosh’SQL进阶教程系列学习笔记&#xff0c;笔记整理比较粗糙&#xff0c;主要目的自存为主&#xff0c;记录完整的学习过程。&#xff08;图片超级多&#xff0c;慎看&#xff01;&#xff09; 【中字】SQL进阶教程 | 史上最易懂S…

Oracle: oracle大小写敏感问题

oracle大小写敏感含义&#xff1a;比如创建表A和a&#xff0c;A和a是两个不同的表&#xff08;表名不同&#xff09;。 oracle大小写不敏感含义&#xff1a;比如创建了A表就不能创建a表&#xff0c;将A和a看成是相同的表&#xff08;表名相同&#xff09;。 1、查询用户是否存…

嵌入式人工智能(47-Pycharm通过SSH远程连接调试树莓派4B服务器)

用过Pycharm的同学都知道&#xff0c;这个IDE非常强大&#xff0c;强大到写个Helloworld都不值当运行它&#xff0c;等我打开的功夫&#xff0c;sublime都运行结束了。但是往往写大项目&#xff0c;尤其是web前后端的程序用Pycharm非常爽了&#xff0c;多标签页&#xff0c;前后…

AI Agent Market: Soverin - 引领未来的AI工具中心

随着人工智能技术的快速发展,AI代理正在成为企业不可或缺的新入口。最近,扎克伯格和黄仁勋的对话强调了AI代理的重要性,将其视为继电子邮件、网站和社交媒体之后的第四大企业必备工具。在这个背景下,Soverin作为一个成熟的AI应用和代理市场平台,正引领着AI工具市场的未来趋…

Android平台RTMP直播推送模块技术接入说明

技术背景 大牛直播SDK跨平台RTMP直播推送模块&#xff0c;始于2015年&#xff0c;支持Windows、Linux&#xff08;x64_64架构|aarch64&#xff09;、Android、iOS平台&#xff0c;支持采集推送摄像头、屏幕、麦克风、扬声器、编码前、编码后数据对接&#xff0c;功能强大&…

XCode15.4真机运行调试

更新Xcode后&#xff0c;没有模拟器内容&#xff0c;而且真机也不显示&#xff0c;编译按钮无法点击&#xff0c;设备在管理运行目标中可见&#xff0c;但无法选中 解决方案&#xff1a;下载iOS17.5模拟器&#xff0c;但最坑的是直接点击“Get”下载总是中断&#xff0c;且无…

mysql幻读现象及其避免策略

mysql幻读现象及其避免策略 1、幻读是什么&#xff1f;2、快照读与当前读3、如何避免幻读&#xff1f;3.1 快照读3.2 当前读 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 1、幻读是什么&#xff1f; 幻读是事务中第二次查询返回了之前不…

Spring Boot 3.x gradle脚手架工程build.gradle详解

为了让读者轻松掌握gradle项目构建脚本中各种配置&#xff0c;我们将从0开始一点点启用配置&#xff0c;以做实验的尝试方式&#xff0c;让大家对各种配置的作用有比较深的印象。如果觉得对你有帮助&#xff0c;记得点赞收藏&#xff0c;关注小卷&#xff0c;后续更精彩&#x…

2024视频编辑网站微服务

文章目录 项目描述流量数据算法主站服务AIGC功能服务视频剪辑服务任务调度服务算法部署服务 项目描述 一款海外视频编辑工具&#xff0c;提供视频编辑、多媒体资源的AI处理、AIGC生成素材等功能。 流量数据 数据: 月活MAU(过去30天活跃用户数)为500万&#xff0c;20%的用户每…

跳蚤市场小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;管理员管理&#xff0c;商品信息管理&#xff0c;论坛管理&#xff0c;收货地址管理&#xff0c;基础数据管理&#xff0c;轮播图信息 微信端账号功能包括&#xff1a;系统首页&a…