【Golang】如何统一处理HTTP请求中的异常捕获
最近写go,路由选择httprouter,现在希望在不修改httprouter源码的前提下,对所有注册的路由handle进行异常捕获。
golang使用panic()产生异常,然后可以recover()来捕获到异常,否则主程序直接宕掉,这是我们不希望看到的。
或者全程检查error,不主动抛出异常。即便这样,可能异常依然不能避免。
func RegRouters(r *httprouter.Router) {
r.GET("/", Home)
r.GET("/contact", Contact)
}
func Home(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
defer func() {
if pr := recover(); pr != nil {
fmt.Printf("panic recover: %v\r\n", pr)
debug.PrintStack()
}
}()
//something
}
func Contact(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
defer func() {
if pr := recover(); pr != nil {
fmt.Printf("panic recover: %v\r\n", pr)
debug.PrintStack()
}
}()
//something
}
正常的路由表长这样,在C#中相当于对每个请求加try...catch,将业务上代码包裹起来。
golang同理:
func RegRouters(r *httprouter.Router) {
r.GET("/", WrapHandle(Home))
r.GET("/contact", WrapHandle(Contact))
}
WrapHandle需要有一个handle类型的参数,同时返回值要能被httprouter接收
func WrapHandle(handle httprouter.Handle) httprouter.Handle {
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
defer func() {
if pr := recover(); pr != nil {
fmt.Printf("panic recover: %v\r\n", pr)
debug.PrintStack()
}
}()
handle(w, r, p)
}
}
加一个上下文,把handle简化一下
func WrapHandle(handle func(ctx *context.Context)) httprouter.Handle {
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
defer func() {
if pr := recover(); pr != nil {
fmt.Println("panic recover: %v", pr)
debug.PrintStack()
}
}()
ctx := context.NewContext(w, r, p)
handle(ctx)
}
}
func Home(ctx *context.Context) {
defer func() {
if pr := recover(); pr != nil {
fmt.Printf("panic recover: %v\r\n", pr)
debug.PrintStack()
}
}()
//something
}
func Contact(ctx *context.Context) {
defer func() {
if pr := recover(); pr != nil {
fmt.Printf("panic recover: %v\r\n", pr)
debug.PrintStack()
}
}()
//something
id = ctx.FormInt64("id") //通过context从FORM取值,并转换为int64
}
这里加了一个context包,handle的参数也减少到一个,主要是context上可以做更多的事情。
一个简单的请求上下文的原型:
type Context struct {
responseWriter http.ResponseWriter
request *http.Request
params httprouter.Params
Data map[string]interface{}
}
func NewContext(w http.ResponseWriter, r *http.Request, params httprouter.Params) *Context {
ctx := new(Context)
ctx.responseWriter = w
ctx.request = r
ctx.params = params
ctx.Data = make(map[string]interface{})
return ctx
}
func (ctx *Context) FormValue(name string) string {
return ctx.request.FormValue(name)
}
func (ctx *Context) FormInt64(name string) int64 {
value, _ := strconv.ParseInt(ctx.FormValue(name), 10, 64)
return value
}
//更多扩展....
好了,先到这里,希望对你有帮助。
【Golang】如何统一处理HTTP请求中的异常捕获的更多相关文章
- Swoole 中协程的使用注意事项及协程中的异常捕获
协程使用注意事项 协程内部禁止使用全局变量,以免发生数据错乱: 协程使用 use 关键字引入外部变量到当前作用域禁止使用引用,以免发生数据错乱: 不能使用类静态变量 Class::$array / 全 ...
- 02 flask 请求钩子、异常捕获、上下文、Flask-Script 扩展、jinja2 模板引擎、csrf防范
一 请求勾子 在客户端和服务器交互的过程中,有些准备工作或扫尾工作需要处理,比如: 在请求开始时,建立数据库连接: 在请求开始时,根据需求进行权限校验: 在请求结束时,指定数据的交互格式: 为了让每个 ...
- [日常] 使用TCPDUMP和Ethereal抓包分析HTTP请求中的异常情况
在测试功能的过程中,出现这样一种现象.前端js发起ajax请求后,在浏览器的审查元素网络状态中可以看到status为pending,等15秒以后js会把当前超时的请求取消掉,变成了红色的cancel. ...
- JAVA 线程中的异常捕获
在java多线程程序中,所有线程都不允许抛出未捕获的checked exception(比如sleep时的InterruptedException),也就是说各个线程需要自己把自己的checked e ...
- C#中的异常捕获机制(try catch finally)
(转自:http://blog.csdn.net/zevin/article/details/6901489) 一.C#的异常处理所用到关键字try 用于检查发生的异常,并帮助发送任何可能的异常.ca ...
- python中的异常捕获怎么用?
http://www.2cto.com/kf/201301/184121.html http://www.w3cschool.cc/python/python-exceptions.html try: ...
- AngularJS 用 Interceptors 来统一处理 HTTP 请求和响应
Web 开发中,除了数据操作之外,最频繁的就是发起和处理各种 HTTP 请求了,加上 HTTP 请求又是异步的,如果在每个请求中来单独捕获各种常规错误,处理各类自定义错误,那将会有大量的功能类似的代码 ...
- 使用domain模块捕获异步回调中的异常
和其他服务器端语言相比,貌似node.js 对于异常捕捉确实非常困难. 首先你会想到try/catch ,但是在使用过程中我们会发现并没有真正将错误控制在try/catch 语句中. 为什么? 答案是 ...
- node.js 使用domain模块捕获异步回调中的异常
和其他服务器端语言相比,貌似node.js 对于异常捕捉确实非常困难. 首先你会想到try/catch ,但是在使用过程中我们会发现并没有真正将错误控制在try/catch 语句中. 为什么? 答案是 ...
随机推荐
- eclipse打包java项目
参考链接:https://blog.csdn.net/heshushun/article/details/78039801
- servlet的继承关系
一.servlet的继承关系 1.servlet程序是sun公司开发用于web资源技术,任何一个类只需要实现了servlet接口,那么就可以成为servlet程序 2.继承体系: ---------- ...
- Java框架spring 学习笔记(五):Bean定义继承
子 bean 的定义继承父定义的配置数据.子定义可以根据需要重写一些值,或者添加其他值. 编写HelloWorld.java package com.example.spring; public cl ...
- TCP报文格式
转载自https://blog.csdn.net/mary19920410/article/details/58030147 1.TCP报文格式 TCP报头中的源端口号和目的端口号同IP数据报中的源I ...
- PhoenixFD插件流体模拟——UI布局【Export】详解
Liquid Export 流体导出 本文主要讲解Export折叠栏中的内容.原文地址:https://docs.chaosgroup.com/display/PHX3MAX/Liquid+Expor ...
- 【JDBC】java.sql.SQLException: The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more than one time zone.
在使用阿里的druid 时,报了一个异常java.sql.SQLException: The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized ...
- FPGA_VHDL 学习课堂笔记001
FPGA_VHDL 学习课堂笔记 记录说明:本文档主要记录大学期间,老师FPGA授课课堂笔记. 代码语言:VHDL 编程软件:MAX+plus II FPGA硬件:FLE-843 03月05日 ...
- ceph mimc版本ceph-deploy安装与配置
系统环境centos7.6 内核5.0.9 YUM源配置 [root@k8s-sys-10-82-4-200 ceph-cluster]# cat /etc/yum.repos.d/ceph.repo ...
- 网络通信实验(1)STM32F4 以太网简介
STM32F4 以太网简介 STM32F407 芯片自带以太网模块,该模块包括带专用 DMA 控制器的 MAC 802.3(介质访问控制)控制器,支持介质独立接口 (MII) 和简化介质独立接口 (R ...
- VLC 用到的那些 YUV 格式
YUV是视频应用中使用的一类像素格式.YUV实际上是所有“YUV”像素格式共有的颜色空间的名称. 与RGB格式(红 - 绿 - 蓝)相对应,YUV颜色用一个称为Y(相当于灰度)的“亮度”分量和两个“色 ...