重視遊戲陪玩app原始碼前端異常監控和容災,保證系統穩定性

雲豹科技程式設計師發表於2021-11-17
所謂的異常就是遊戲陪玩app原始碼出現了意料之外的情況,影響了程式最終的呈現結果。所以我們開發遊戲陪玩app原始碼的時候就非常有必要未雨綢繆,進行異常監控,以應對突如其來的問題
實現遊戲陪玩app原始碼前端異常監控和容災,既可以增強使用者體驗,我們開發者也能遠端定位問題,尤其是移動端
儘管對 JS 而言,異常一般只會使前端異常監控和容災當前執行的任務中止,基本不會導致崩潰,可異常監控卻是一個完善的前端方案必須具備的,接下來就針對我們前端,需要做的異常一一說明

異常監控

JS 執行異常
  • 使用try-catch的話捕捉不到前端異常監控和容災具體語法錯誤和非同步錯誤,所以推薦用在可預見情況下的錯誤監控
  • 使用 window.onerror ,比try-catch強,不過也捕獲不到資源載入異常或者介面異常,推薦用來捕獲預料之外的錯誤
兩者結合更好
重視遊戲陪玩app原始碼前端異常監控和容災,保證系統穩定性
收集到的錯誤資訊列印出來是這樣子的
重視遊戲陪玩app原始碼前端異常監控和容災,保證系統穩定性
window.onerror = function (msg, url, row, col, error) {
    console.table({ msg, url, row, col, error: error.stack })
    let errorMsg = {
        type: 'javascript',
        // msg錯誤訊息,error是錯誤物件,這裡拿的是error.stack(異常資訊)
        msg: error && error.stack ? error.stack || msg, 
        // 發生錯誤的行數
        row,
        // 列數,也就是第幾個字元
        col,
        // 發生錯誤的頁面地址
        url,
        // 發生錯誤的時間
        time: Date.now()
    }
    
    // 然後可以把這個 errorMsg 存到一個陣列裡,統一上報
    // 也可以直接上報
    Axios.post({ '})
    
    // 如果return true,錯誤就不會拋到控制檯
}
上報有兩種方式,一種是如上面程式碼中的用 AJAX,會有跨域所以需要遊戲陪玩app原始碼服務端支援;還有一種是用 Image 物件,這有一個好處就是圖片請求沒有跨域;注意URL長度不要超過限制就行。後面的例子中就不一一列舉了
let url = '錯誤資訊'
new Image.src = url
iframe 異常
捕獲 iframe 異常和 JS 執行差不多
<iframe src="xxx.html"></iframe>
<script>
    window.iframe[0].onerror = function (msg, url, row, col, error) {
        //和上面 JS 異常一樣
    })
</scrpt>
資源載入異常
使用 addEventListener(‘error’, callback, true) 在捕獲階段捕捉資源載入錯誤資訊,然後上報遊戲陪玩app原始碼伺服器
addEventListener('error', e => {
    const targe = e.target
    if(target != window){
        //這裡收集錯誤資訊
        let errorMsg = {
            type: target.localName, // 錯誤來源名稱。比如圖片這裡就是'img'
            url: target.src || target.href, //錯誤來源的連結
            // .... 還需要其他資訊可以自己補充
        }
        // 把這個 errorMsg 存到一個陣列裡,然後統一上報
        // 或者直接上報
        Axios.post({ '})
    }
}, true)
Promise 異常
使用 addeventListener(‘unhandledrejection’,callback)捕獲 Promise 錯誤。不過捕捉不到行數
window.addEventListener("unhandledrejection", (e) => {
    console.log(e)
    let errorMsg = {
        type: 'promise',
        msg: e.reason.stack || e.reason
        // .....
    }
    Axios.post({ '})
    
    // 如果return true,錯誤就不會拋到控制檯
})
new Promise(() => {
    s
})
列印出來是這麼個東西
重視遊戲陪玩app原始碼前端異常監控和容災,保證系統穩定性
Vue 異常
errorHandle
Vue為元件呈現函式和監視程式期間沒有捕獲的錯誤分配的一個處理程式。不過這個方法一旦捕獲取錯誤後,錯誤就不會拋到遊戲陪玩app原始碼控制檯
Vue.config.errorHandler = (err, vm, info) => {
    // err 錯誤處理
    // vm vue例項
    // info 是特定於vue的錯誤資訊,比如哪個生命週期勾子
    // 如果需要把錯誤拋到控制檯,需要在這裡加上這一行
    console.error(err)
}
warnHandle
是Vue警告分配一個自定義處理程式。不過只在遊戲陪玩app原始碼開發環境有效,生產環境會被自忽略
Vue.config.warnHandle = (msg, vm, trace){
    // trace 是元件層次結構
}
renderError
預設的渲染函式遇到錯誤時,提供了一個代替渲染輸出的。這個和熱重新載入一起用會很棒
new Vue({
    render (h){
        throw new Error('oops')
    },
    renderError (h, err){
        return h('per',{ style: { color: red } }, err.stack)
    }
}).$mount('#app')
errorCaptured
任何派生元件捕獲錯誤時呼叫。它可以 return false 來阻止錯誤傳播。可以在這個勾子裡修改元件狀態。不過如果是在模板或呈現函式裡有條件語句,在捕獲到錯誤時,這些條件語句會短路,可能進入一個無限渲染迴圈
Vue.component('ErrorBoundary',{
    data: () => { ... }
    errorCaptured(err, vm, info){
        // err 錯誤資訊  
        // vm 觸發錯誤的元件例項 
        // info 錯誤捕獲位置資訊
        return false
    }
})
React 異常
getDerivedStateFromError
React 也有自帶的捕獲遊戲陪玩app原始碼所有子元件中錯誤的方法,這個生命週期會在後代元件丟擲錯誤時被呼叫。注意這個是在渲染階段呼叫的,所以不允許出現副作用
class ErrorBoundary extends React.Component {
    constructor(props) {
        super(props)
        this.state = { hasError: false }
    } 
    static getDerivedStateFromError(error) {
        // 更新 state 使下一次渲染可以顯降級 UI
        return { hasError: true }
    }
}
componentDidCatch
這個生命週期也會在後代元件丟擲錯誤時被呼叫,但是不會捕獲遊戲陪玩app原始碼事件處理器和非同步程式碼的異常。它會在【提交】階段被呼叫,所以允許出現副作用
class ErrorBoundary extends React.Component {
    constructor(props) {
        super(props)
    } 
    componentDidCatch(error, info){
        // error 錯誤資訊
        // info.componentStack 錯誤元件位置
    }
}
說了遊戲陪玩app原始碼前端可能發生的各種異常處理,那麼遊戲陪玩app原始碼後端異常呢?前端容災就是

前端容災

遊戲陪玩app原始碼前端容災指的因為各種原因後端介面掛了(比如伺服器斷電斷網等等),前端依然能保證頁面資訊能完整展示。
比如 banner 或者列表之類的等等資料是從介面獲取的,要是介面獲取不到了,怎麼辦呢?
LocalStorage
首先,使用 LocalStorage
在介面正常返回的時候把資料都存到 LocalStorage ,可以把介面路徑作為 key,返回的資料作為 value
然後之次再請求,只要請求失敗,就讀取 LocalStorage,把上次的資料拿出來展示,並上報錯誤資訊,以獲得緩衝時間
CDN
同時,每次更新都要備份一份靜態資料放到CDN
在遊戲陪玩app原始碼介面請求失敗的時候,並且 LocalStorage 也沒有資料的情況下,就去 CDN 摘取備份的靜態資料
Service Worker
假如不只是遊戲陪玩app原始碼的介面資料,整個 html 都想存起來,就可以使用 Service Worker 做離線儲存
利用 Service Worker 的請求攔截,不管是存介面資料,還是存頁面靜態資原始檔都可以
// 攔截所有請求事件 快取中有請求的資料就直接用快取,否則去請求資料 
self.addEventListener('fetch', e => { 
    // 查詢request中被快取命中的response 
    e.respondWith(caches.match(e.request).then( response => { 
        if (response) { 
            return response 
        } 
        console.log('fetch source') 
    })) 
})
做好這些,遊戲陪玩app原始碼就完全可以正常穩定的執行了。
本文轉載自網路,轉載僅為分享乾貨知識,如有侵權歡迎聯絡雲豹科技進行刪除處理


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69996194/viewspace-2842700/,如需轉載,請註明出處,否則將追究法律責任。

相關文章