一个神秘现象引发对beego框架的思考
小强最近在项目中遇到了一个很奇怪的问题:在整改日志规范时,为了避免影响现有的代码结构以及改动尽可能小的前提下,在调用记日志的SDK处将某一个字段值首字母改为大写,代码示例如下:
fmt.Println("--------SayHello begin------------")
//项目中这里的a实际是作为参数传入,只是可能为空串,不为空串,这样写肯定没问题
a := ""
b := strings.ToUpper(a[:1]) + a[1:]
fmt.Println("b is ", b)
fmt.Println("--------SayHello end------------")
this.Ctx.Output.Body(this.Ctx.Input.RequestBody)
项目中这里的a变量其实是作为参数传入,只是可能为空串。a变量不为空串时,这样写肯定没问题。但是当为空串时,即""时,就会出问题,在java中,运行的时候肯定会报一个“数组下表越界”的异常。小强将工程编译后生成二进制文件,放到服务器上跑,测试修改后的日志是否符合规范,验了一遍,没有问题,然后就将代码提交了。
之后版本出来测试时发现,有个奇怪的现象:接口不返回任何东西,状态码依然是 200 OK。这让小强很纳闷儿,还好,我们的小强经验丰富,还是解决过大bug的人,然后就根据接口走了一遍代码流程,眉头一皱,就知道问题所在了。原来就是a变量有时候传进来是空字符串,导致出现了slice下标越界的panic,说干就干,小强赶紧做了空串的判断逻辑,重新验了一把,问题就解决了。
小强是爱思考的孩子,不止要解决问题,也要知其所以然。小强在想,出现了panic咋日志里面啥都不打呢,而且还返回200,甚是疑惑。然后就在网上查资料,然后自己又看了beego的源码,就明白了。不得不说,开源就是好啊。
原来问题是这样,小强项目中使用的beego版本是1.6.1版。
小强查到了beego的错误处理流程:beego通过beego.App.Server.Handler处理所有的HTTP请求,在beego.Run()函数中,这个Handler就被设置为app.Handlers,可以参见beego1.6.1版本app.go的第95行:
app.Server.Handler = app.Handlers
而app在一开始就被初始化,可以看app.go中的init()函数,其中调用了NewApp()函数:
// NewApp returns a new beego application.
func NewApp() *App {
cr := NewControllerRegister()
app := &App{Handlers: cr, Server: &http.Server{}}
return app
}
可以看出,把cr赋值给Handler,其实cr是ControllerRegister类型,ControllerRegister类型实现了http.Handler接口,具体实现可以看router.go的第600行ServeHTTP方法。该方法中(第612行)有如下语句:
defer p.recoverPanic(context)
golang语言的错误处理机制是,当在某处调用panic(string)后,panic之后的语句将不再执行,而是通过调用关系逐级退出,在每一级调用处都通过defer处理函数检查是否panic被recover()函数捕获处理,如果没有则继续往上扔panic信息,如果已经被捕获则结束此次panic过程,由捕获panic的函数处继续往下执行。
出现异常会执行recoverPanic方法,该方法中(第864行)有这样的代码段:
if BConfig.RunMode == DEV {
showErr(err, context, stack)
}
showErr函数中会对错误进行模板渲染,而小强项目早在现网中投入使用,RunMode为prod,而非dev,所以recover()后不会有错误提示。
当RunMode为prod时:

当RunMode为prod时:

dev模式好歹会返回错误信息:slice bounds out of range
prod模式没有任何提示。下标越界这种问题看似简单,但是真正遇到了有时候也会摸不着头脑。
本公众号免费提供csdn下载服务,海量IT学习资源,如果你准备入IT坑,励志成为优秀的程序猿,那么这些资源很适合你,包括但不限于java、go、python、springcloud、elk、嵌入式 、大数据、面试资料、前端 等资源。同时我们组建了一个技术交流群,里面有很多大佬,会不定时分享技术文章,如果你想来一起学习提高,可以公众号后台回复【2】,免费邀请加技术交流群互相学习提高,会不定期分享编程IT相关资源。
扫码关注,精彩内容第一时间推给你

一个神秘现象引发对beego框架的思考的更多相关文章
- go beego框架 入门使用 (一)
---恢复内容开始--- 谢谢您花时间读我写的随笔,有问题的话欢迎留言,看到的话都会回复的! beego框架 分为Web版,Api版 api版目录 web版目录 (区别 : ...
- Beego框架的一条神秘日志引发的思考
公司目前的后台是用Beego框架搭的,并且为了服务的不中断升级,我们开启了Beego的Grace模块,用于热升级支持.一切都跑井然有序,直到有一天,领导甩出一些服务日志,告知程序一直报错: 2018/ ...
- 转:一个Sqrt函数引发的血案
转自:http://www.cnblogs.com/pkuoliver/archive/2010/10/06/1844725.html 源码下载地址:http://diducoder.com/sotr ...
- 一个Sqrt函数引发的血案(转)
作者: 码农1946 来源: 博客园 发布时间: 2013-10-09 11:37 阅读: 4556 次 推荐: 41 原文链接 [收藏] 好吧,我承认我标题党了,不过既然你来了, ...
- Beego 框架学习(一)
Beego官网本身已经整理的非常详细了,但是作为一个学习者,我还是决定自己好好整理一下,这样在后面使用的时候自己对每部分才能非常熟悉,及时忘记了,也可以迅速定位自己要用的知识在哪里.当然也是对官网的一 ...
- 初次使用beego框架
安装beego框架以及bee工具 go get -u github.com/astaxie/beego go get github.com/beego/bee 创建一个新项目 bee new weba ...
- Go语言之高级篇beego框架安装与使用
一.beego框架 1.beego框架简介 beego 是一个快速开发 Go 应用的 HTTP 框架,他可以用来快速开发 API.Web 及后端服务等各种应用,是一个 RESTful 的框架,主要设计 ...
- 【转载】一个Sqrt函数引发的血案
转自:http://www.cnblogs.com/pkuoliver/archive/2010/10/06/sotry-about-sqrt.html 源码下载地址:http://diducoder ...
- 一个Sqrt函数引发的血案
源码下载地址:http://diducoder.com/sotry-about-sqrt.html 好吧,我承认我标题党了,不过既然你来了,就认真看下去吧,保证你有收获. 我们平时经常会有一些数据运算 ...
随机推荐
- 网页去重之Simhash算法
Simhash算法是Google应用在网页去重中的一个常用算法,在开始讲解Simhash之前,先了解——什么是网页去重?为什么要进行网页去重?如何进行网页去重,其基本框架是什么? 网页去重,顾名思 ...
- java架构师视频教程 内含activemq+jvm+netty+dubbo
目录: 架构师视频教程包含activemq jvm netty dubbo 0分布式项目实战所有视频(分布式项目视频)互联网架构师第二期-视频部分互联网架构师第二期-资料部分1.Netty快速入门教程 ...
- 026 模块3-random库的使用
目录 一.random库基本介绍 1.1 random库概述 二.基本随机数函数 2.1 随机数种子 三.扩展随机数函数 3.1 随机数函数的使用 一.random库基本介绍 random库是使用随机 ...
- 1512: [POI2006]Pro-Professor Szu
首先把边反向, 问题转化成求从主建筑楼走向各个点的方案数. 然后缩点,块中的方案数可以直接算. 设f[i]表示走到第i个点的方案数.显然f[i]=∑f[j](存在newedge(j,i))初始时,f[ ...
- Abstract Factory抽象工厂模式
抽象工厂模式是是用一个超级工厂去创建其他工厂,简单点说就是工厂的父类,属于创建型模式. 目标:提供一个创建一组对象的方法,而无需指定它们具体的类(同工厂方法). 使用场景:系统的产品有多于一个的产品族 ...
- LeetCode第七题
Reverse digits of an integer. Example1: x = 123, return 321Example2: x = -123, return -321 Have you ...
- Oracle SQL调优之绑定变量用法简介
目录 一.SQL执行过程简介 二.绑定变量典型用法 2.1.在SQL中绑定变量 2.2.在PL/SQL中使用绑定变量 2.3.PL/SQL批量绑定变量 2.4.Java代码里使用绑定变量 最近在看&l ...
- 手把手教你使用Java实现一个神经网络
首先看一下运行效果: 下面是项目整体目录: 0.实现神经网络总览 神经网络由层.神经元.权重.激活函数和偏置组成.每层都有一个或者多个神经元,每一个神经元都和神经输入/输出连接,这些连接就是权重. 需 ...
- Winform去掉标题栏后移动窗体
第一步:声明全局变量-> private Point _HoverTreePosition; 第二步: #region 隐藏标题栏后移动窗口 private void Form_HoverTr ...
- centos7 supervisor管理redis
centos7 supervisor管理redis 标签(空格分隔): linux,redis 概念 Supervisor 相当强大,提供了很丰富的功能,不过我们可能只需要用到其中一小部分 super ...