1. 程式人生 > >專案接入apm後錯誤報警總結

專案接入apm後錯誤報警總結

此文已由作者張磊授權網易雲社群釋出。

歡迎訪問網易雲社群,瞭解更多網易技術產品運營經驗。

前言:


後端服務一般都有監控措施,一般可以及時發現線上錯誤,但是很多專案的前端卻沒有線上報警服務,即使有錯誤,前端根本無法感知,但實際上使用者使用的系統、瀏覽器等環境十分複雜,還是有比較高的概率出現 bug 的。這時候線上錯誤的發現,一般有三個方向,要麼依賴於使用者報告,要麼依賴於測試發現,要麼是自己使用中發現問題。依靠使用者報告,這就嚴重影響了體驗,而且很多使用者不會報告或者其他原因復現率低,導致沒有報告。所以為了解決該問題,那前端需要一個服務,遇到錯誤的時候,能主動上報問題,並作提醒,進行排查。同時也可以在測試環境也部署該服務,有時候測試沒有發現的問題,但這個主動上報就能幫我們提早發現程式碼 bug,再者我們可以和使用者同時接收到錯誤資訊,那麼我們就可以及早修復問題,把問題的影響儘可能的縮小,靜默解決。


環境:

專案是 NEJ 和 regular 開發的,以 SPA 頁面為主。


實施:

這裡是使用 apm 作為線上報警的基礎服務。同時對線上線下環境分開處理。


階段成果:

上線該服務幾個月,線上線下的報錯發現的有幾十個。最近越來越穩定,出錯率越來越低了。當然也遇到了一些很難復現的 bug。


錯誤分析:

如果把錯誤僅僅當成錯誤來看,這肯定是不對的,應該從錯誤中發現些什麼,以後注意那些坑,畢竟已經有幾十個錯誤作為參照物了,也可以拿來分析了。錯誤可以歸為幾類:


  1. Uncaught TypeError: Cannot read property 'ref0' of null這種一般是在 setTimeout 裡對 this.$refs 進行操作,一般做法是在 setTimeout 裡,進行二次檢測,但更好的做法是 clearTimeout。

  2. Uncaught TypeError: Cannot read property '__cache' of undefined這種一般是在 setTimeout 裡對介面請求進行操作,此時路由頁面已經觸發 destory 掉了,導致訪問 this 物件獲取不到對應的方法。一般做法是在 setTimeout 裡,進行二次檢測,但更好的做法是 clearTimeout。

  3. 機率出錯線下測試程式碼無問題發生,但是線上使用者報錯,這裡一般是沒有寫清楚邊界情況造成的。解決方案,通過錯誤查詢到對應程式碼,分析邏輯。

  4. Uncaught TypeError: Cannot read property 'indexOf'/'replace' of undefined後端資料返回不規範造成的,可能約定是 string 但是實際中沒有返回值,又或者介面的錯誤處理有問題造成的。實際上兩者皆有。

  5. 引入公司其他服務指令碼報錯 這些指令碼的錯誤,一般是通知相關人員進行 fix。

  6. 因為擴充套件導致的報錯 曾經一個測試裝了一個擴充套件,只要訪問某些頁面,短時間可以出現 1000+ 的錯誤

  7. 第三方瀏覽器,或者手機瀏覽器報錯

    錯誤資訊    
    SecurityError (DOM Exception 18): Blocked a frame with origin "https://a.com" from accessing a frame with origin "https://b.com". Protocols, domains, and ports must match.
    堆疊資訊    
    [email protected]://a.com/#/m/a/:54:[email protected]://a.com/#/m/a/:68:[email protected]://a.com/#/m/a/:115:[email protected]://a.com/#/m/a/:151:42global [email protected]://a.com/#/m/a/:320:26

    這種一般是第三方加的指令碼,忽略即可。

  8. Uncaught ReferenceError: t is not defined這個錯誤,一開始覺得和1、2是類似的,邊界未處理,再加上是 lib 庫的程式碼。後來實際上研究了邏輯,才發現使用的 lib 部分程式碼丟失,在處理 ctrl + up 的時候的回撥函式沒了。。。後續解決方案,研究了下邏輯,不影響使用,刪掉該段程式碼。


靜態資源和後臺服務不同源

後來對靜態資源單獨一個域名,一開始沒有考慮到不同源的問題,apm 不報錯,以為是程式碼質量好了很多。後來發現錯誤集中在 firefox、ie 上,錯誤資訊都是 script error。想到域名的問題,才發現 apm 相當於停止工作一段時間了。這個問題的解決方案,需要對 nej 打包進行處理,允許 script 標籤新增屬性。同時允許非同步載入的 script 新增屬性即可。接著對靜態資源的伺服器新增跨域 header 配置。


Access-Control-Allow-Origin: *

參考

  1. https://stackoverflow.com/questions/28901166/how-do-i-add-the-crossorigin-tag-to-a-dynamically-loaded-script

  2. https://developer.mozilla.org/zh-CN/docs/Web/API/GlobalEventHandlers/onerror

  3. http://www.alloyteam.com/2017/03/jserror1/


免費體驗雲安全(易盾)內容安全、驗證碼等服務

更多網易技術、產品、運營經驗分享請點選


相關文章:
【推薦】 資料倉庫建設之六脈神劍
【推薦】 知物由學 | 虛假色情氾濫,人工智慧可以做些啥?
【推薦】 BugBash活動分享