Error information collection scheme:

Front-end errors include code execution errors and resource loading errors

A, try to catch

Try {// block} catch(e){Copy the code

This approach requires the developer to manually wrap the estimated risk of error, which can be done manually or through automated tools and libraries. Automation tools are also implemented based on AST, such as UglityJS.

Try catch features: Fine for handling run-time non-asynchronous errors, but not syntactic and asynchronous errors.

Try {var a = \ 'a'}catch(e){console.log(e)} // Can not catch -- syntax error try{var a = \ 'a'}catch(e){console.log(e)} // Async try{setTimeout(()=>{a})} catch(e){console.log(e)} // Add another layer of try catch to setTimeoutCopy the code

Summary: Try catch is limited and intrusive

Window. onerror– Event bubbling

Window.onerror can handle syntax and runtime exceptions (which can be caught asynchronously), but it can’t handle syntax and network errors (because network request exceptions don’t bubble up). The code is less intrusive, and you don’t need to automatically insert scripts into the code through the AST.

window.onerror = function(message, source, lineno, colno, error) { ... }
Copy the code
  • Message: error message (string).
  • Source: THE URL (string) of the script that raised the error
  • Lineno: Line number (value) where the error occurred
  • Colno: Column number (value) of the row where the error occurred
  • Error: An error object (object) such as error.stack retrieves the error stack

Error handling for cross-domain scripts:

Window. onerror does not capture valid information for js files in different fields. For security reasons, error messages returned by different browsers may have different parameters. Window. onerror cannot catch exception information in many browsers, and script error will be returned. So the script needs to be set up

crossorigin="anonymous"
Copy the code

Use the Source Map for error restoration

Iii. Error information processing of Promise

The habit of encouraging promises to end with a catch function can be checked by using the ESLint plugin eslint-plugin-Promise.

The promise error occurs by catching the event unHandlerejection

window.addEventListener('unhandledrejection',e=>{
    console.log(e)
})
Copy the code

4. Network exception and error handling

You can perform the following operations:

<script src"**.js" onerror="errorHandle(this)"></script>
Copy the code

Or catch with the: window.addeventListener (‘error’) event

window.addEventListener('error',e=>{
    console.log(e)
},true)
Copy the code

Window.onerror and window.addeventListener (‘error’) can be used to distinguish network loading errors from other common errors

window.addEventListener('error',e=>{ if(! E.message){// Network resource loading error}},true)Copy the code

Window.onerror differs from window.addeventListener (‘error’) :

  • Window. onerror: bubble, need to perform function assignment, repeated declaration will be replaced

  • Window.addeventlistener (‘error’): Capture, which can bind multiple callback functions, in the order in which they are bound

Five, page crash collection and processing

Handle by listening for load and beforeUnload under the window pair and combine with sessionStorage

window.addEventListener('load',()=>{ sessionStorage.setTitem('page_exit','pending') }) window.addEventListener('beforeunload',()=>{ sessionStorage.setTitem('page_exit','true') }) sessionStorage.getTitem('page_exit')! ='true' // page crashesCopy the code

Vi. Error handling of VUE framework

Vue.config.errorHandler Outputs errors caught by vue.config. errorHandler as console.error

Vue.config.errorHandler = function (err, vm, info) { reportError({ code: 'xx', msg: encodeURIComponent(err), action: 'vue-render-error', line: info, attach2: err && err.stack || '' }); };Copy the code

So you can hijack console.error to catch errors in the framework

const nativeConsoleError = window.console.error window.console.error = (.. args)=>nativeConsoleError.apply(this,args)Copy the code

The performance data

Monitoring indicators: first rendering time (FP), first content rendering time (FCP), first meaningful rendering time (FMP), first screen time, user interaction time (TTI)

Key data Time:

var navigasitonInfo = null; if (typeof performance ! = 'undefined' && typeof performance.getEntriesByType ! = 'undefined') { navigasitonInfo = performance.getEntriesByType('navigation')[0]; }; let timing = window.performance.timing; // Page complete load time let complete_load_duration = timing. Loadeventend-timing. NavigationStart // Page white screen time let white_screen_duration NavigationStart // first screen time let first_screen_duration = calcFirstScreen( Interactive_duration = timing. DomContentLoadedEventEnd - timing. NavigationStart / / ready to take the let stalled_duration = DomainLookupStart - timing. NavigationStart // Let redirect_duration = timing. RedirectEnd - RedirectStart // DNS parsing time let dns_duration = timing. DomainLookupEnd - timing. DomainLookupStart // IP connection time let Ip_connect_duration = timing. ConnectEnd - timing. ConnectStart // First packet duration let first_data_duration = timing Let final_data_duration = timing. ResponseEnd - (timing. RequestStart? timing.requestStart:timing.fetchStart)), Dom_operate_duration = timing. Domcomplete-timing. DomLoading let res_load_duration = Duration // Current page file size let res_size = navigasitonInfo? navigasitonInfo.transferSize : 0 function calcFirstScreen() { var timing = window.performance.timing; var firstScreen = timing.loadEventStart - timing.navigationStart; if (typeof window.performance ! = 'undefined' && typeof window.performance.getEntriesByName ! = 'undefined'){ try{ var iHeight = window.innerHeight; var iWidth = window.innerWidth; var imgList = document.querySelectorAll('img'); var loadEventDuration = timing.loadEventEnd - timing.navigationStart; for (var i=0,j=imgList.length; i<j; i++){ var target = imgList[i]; if (typeof target.getBoundingClientRect ! = 'undefined' && target.src) { var rectInfo = target.getBoundingClientRect(); if (rectInfo){ var pageYOffset = window.pageYOffset; var topH = rectInfo.top + pageYOffset; if (topH < iHeight && rectInfo.left >=0 &&rectInfo.left<iWidth){ var perList = window.performance.getEntriesByName(target.src); if (perList.length){ var targetPer = perList[0]; if (targetPer.fetchStart < loadEventDuration){ firstScreen = targetPer.responseEnd; }; }; }; }; }; }; }catch (e) { } }; return firstScreen; }Copy the code

Error reporting

It is better to use a separate domain name to avoid the pressure on the service server and the limit on the number of concurrent requests for the same domain name

Reporting Method:

1, the form of pictures

Images do not involve cross-domain problems, using the method of constructing empty Image objects

let reportUrl = 'xxurl.json'; let reportImg= new Image(); let dataStr = paramStr(xxx); reportImg.src = newReportUrl + '? ' + dataStr;Copy the code

2, the navigator. SendBeacon

Using the sendBeacon() method allows the user agent to asynchronously send data to the server when the opportunity presents itself, without delaying the page’s unload or affecting the load performance of the next navigation. This solves all the problems of submitting analysis data: the data is reliable, the transfer is asynchronous, and the next page load is not affected.

window.addEventListener('unload', logData, false);

function logData() {
    navigator.sendBeacon("/log", analyticsData);
}
Copy the code

Reporting Time:

  • Pages load and refresh
  • Page Switching route
  • Page is closed
  • The page TAB is visible again