1. 程式人生 > >一個神祕現象引發對beego框架的思考

一個神祕現象引發對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框架思考

小強最近在專案中遇到了一個很奇怪的問題:在整改日誌規範時,為了避免影響現有的程式碼結構以及改動儘可能小的前提下,在呼叫記日誌的SDK處將某一個欄位值首字母改為大寫,程式碼示例如下: fmt.Println("--------SayHello begin------------") //專

從app.route裝飾器引發endpoint的思考

從app.route裝飾器引發對endpoint的思考 還是先來看看原始碼     def route(self, rule, **options):         """A decorator that is used to reg

一個業務邏輯引發多表連接的思考

tro 完成 插入語 多表 應該 left () 業務 exec StringBuilder sb = new StringBuilder(); sb.Append("insert into lx_ZBBaoYangLog(M

討論過後而引發EF 6.x和EF Core查詢緩存的思考

entity order by 跟著 framework 二次 不一定 write 當前 希望 前言 最近將RabbitMQ正式封裝引入到.NET Core 2.0項目當中,之前從未接觸過這個高大上的東東跟著老大學習中,其中收獲不少,本打算再看看RabbitMQ有時間寫寫

一次內聯元素錯位引發line-height的思考

作者:李一睿 line-height 對於一個前端小可愛來說,應該是一個會經常碰面的老朋友了。可是有一天,我突然發現自己好像對他沒那麼瞭解,他也沒有外表看起來的那麼簡單。 事情的經過是這樣的…… 在偶然一次工作中,我寫了這樣的模板: <div> <span clas

java的nextLine()的一個報錯引發思考

寫在最前面: 晚上幫一位同學看一段程式碼,程式碼很入門,不過是java的,還好我也是懂java的男人,哼哼   程式碼如下,我做了一點調整,方便看輸出: package Arithmetic; import java.util.Scanner; class PayCh

一個死鎖引發思考

筆者在轉到 golang 之後使用最多的就是 Grpc 的庫,這次裸寫 tcp 的 client ,由於 client 的 write 阻塞間接導致了程式碼死鎖,在此處記錄下。 client write 的分類 寫成功 「寫成功」指的是 write 呼叫返回的

關於字串也可以是物件,引發typeof的思考

文章目錄 問題背景 寫在前面 問題解答 物件建立 物件分類 複習函式物件的建立方法 問題背景 今天在看JS教程時,發現以下這個例子: var x="john"; var

Beego框架學習筆記04--Beego與多多關係表資料操作

1.Beego Orm Read方法注意事項 使用orm根據指定欄位去資料庫中檢索資訊的時候,Read方法的第一個引數應當是【承載資訊物件的指標】而不是承載資訊物件。 ... o := orm.NewOrm() var articleType models.ArticleTyp

一個條件判斷引發思考

有一套web系統,會部署到不同的伺服器上分別執行,這套系統類似於市面上的OA系統一樣, OA開發商會給不同的企業客戶部署一套獨立的互不關聯的系統,我維護的這套系統也差不多,分別被部署在互不關聯的伺服器上,當然,這些系統的程式碼是同一套,功能也都是相同的。 前兩天,有客戶反饋,他們系統的某個功能無法正常使

再談HashMap-由一個實際問題引發HashMap設計吐嘈

前言        這一篇主要想講一講HashMap在設計上的缺陷以及在使用的過程中留下的一些隱患。也是在實際專案中可能需要注意的一些地方。比如說我下面要介紹的一個containsKey方法,以及List裡面其實有一個toArray[]方法返回的是一個Object[]陣列的

一個30歲男人愛情婚姻的思考

今年30了,結婚4年多了。平心而論,我的婚姻生活很幸福,但是很多時候我似乎並不滿足。因為,我妻子是一個沒有正式工作的人,現在給別人打工,也不可能有什麼發展。文憑也不高,估計再過幾年,也就會成為全職的家庭主婦,的收入尚可,因此,到目前為止,我們還沒有感到很大的經濟壓力。但是,以

【反傳銷】春節一個短暫誤入傳銷和脫身的真實故事以及技術的思考(四)結束後的技術思考

  這是一段真實的,沉甸甸的經歷,就發生在今年春節前後。希望看到這篇文章的每一個人 仔細讀完,理解,並轉發給身邊的人,讓你的家人出門之前一定要注意。同時也可以給已經有陷入傳銷的家人,你們可以做的一些事情。作為一個喜歡技術的,看完之後也思考了一些問題,希望大家一起交流。  自由誠可貴,且行且珍惜。

【反傳銷】春節一個短暫誤入傳銷和脫身的真實故事以及技術的思考(三)回憶、傳銷特徵與解救

  這是一段真實的,沉甸甸的經歷,就發生在今年春節前後。希望看到這篇文章的每一個人 仔細讀完,理解,並轉發給身邊的人,讓你的家人出門之前一定要注意。同時也可以給已經有陷入傳銷的家人,你們可以做的一些事情。作為一個喜歡技術的,看完之後也思考了一些問題,如果能在法律允許的範圍內,通過手機等裝置,保護自身安

【反傳銷】春節一個短暫誤入傳銷和脫身的真實故事以及技術的思考

  這是一段真實的,沉甸甸的經歷,就發生在今年2015春節前後。希望看到這篇文章的每一個人 仔細讀完,理解,並轉發給身邊的人,讓你的家人出門之前一定要注意。同時也可以給已經有陷入傳銷的家人,你們可以做的一些事情。作為一個喜歡技術的,看完之後也思考了一些問題,如何能在法律允許的範圍內,通過手機等裝置,保

【反傳銷】春節一個短暫誤入傳銷和脫身的真實故事以及技術的思考(二)回家之路

 這是一段真實的,沉甸甸的經歷,就發生在今年春節前後。希望看到這篇文章的每一個人 仔細讀完,理解,並轉發給身邊的人,讓你的家人出門之前一定要注意。同時也可以給已經有陷入傳銷的家人,你們可以做的一些事情。作為一個喜歡技術的,看完之後也思考了一些問題,如何能在法律允許的範圍內,通過手機等裝置,保護自身及親

一次外場宕機引發linux記憶體管理的進一步思考--Linux虛擬地址空間如何分佈

0x01 緣由         外場一次伺服器宕機,一群人baba的上去圍觀,分析問題,大部分是猜測,通過回退版本後只解決了問題表象,內在的真實原因沒確定。伺服器上執行著JAVA程式和C程式,到底是什麼導致這次宕機事故。通過分析日誌發現有類似如下錯誤: test_me

一次“淘寶購物”引發出來產品的思考

b)告訴使用者,哪些關鍵點必須注意,否則會影響安裝質量,有點東西安裝錯了,會導致木板損壞,很難恢復(例如:塑料螺帽安裝到木板的小孔中的時候,不能砸得太狠,必須保證跟木板齊平,突出來會讓木板銜接不密封,太深了會讓螺絲無法卡在旋轉螺帽中) (adsbygoogle = window.a

由StreamWriter.WriteLine 引發C#多執行緒的深入思考(一)

http://blog.csdn.net/nndtdx/article/details/6789810 首先,StreamWriter執行緒安全麼? 答:StreamWriter 的構造以及StreamWriter.WriteLine(string)都是非

利用Vuforia開發一個AR卡牌戰(一):多圖識別+EventHandler框架

卡牌對戰1:多圖識別+EventHandler框架 這個系列主要講解實現一個簡易的AR卡牌對戰的功能,這次首先實現多圖識別和EventHandler的框架介紹。 首先我們來實現多圖識別。 1.上傳識別圖並下載資料包,然後得到LicenseKey。這裡用了兩個識別圖,一次打包