In the usual work, JS error is a common situation, especially some errors may not come out when we test locally, when released to the online can be found, if the rescue in time, that is ok, if it is very late

Now, that could cause a lot of damage. If our front end can monitor this error and report it in time, our problem will be better solved. So today we’re going to talk about exception monitoring for front-end code

What are front-end code exceptions

For general syntax errors and runtime errors, browsers display error messages on the console, along with the file, line number, and stack information that failed.

Let’s start with what a front-end code exception means. Front-end code exceptions refer to the following two conditions:

1. There are syntax errors in JS scripts;

2. An error occurs when the JS script is running.

Something like this:

for(var i=0; iCopy the code

 

So how do we catch this exception? There are two ways,

The first is try.. catch

The second is window.onerror

Since a try. Catch can't catch a global error event, you can only catch an error in a try catch block. So the way we exclude it here,

To take the second method, the window.onerror method.

 

window.onerror

Open the browser's developer tools, and when an error occurs, we can immediately be notified, and know where the error occurred and call stack information.

Window.onerror can be used to catch various script execution exceptions on a page, which can help us obtain useful information. But there are compatibility issues with this approach, and the data is not completely consistent across browsers,

Some outdated browsers provide only partial data. It can be used as follows:

window.onerror = function (message, url, lineNo, columnNo, error)Copy the code

 

The meanings of the five parameters are as follows:

1. Message {String} error message The error description is straightforward, but sometimes you can't tell, especially if the script is compressed.

2, the url {String} error corresponds to the script path, such as your http://a.js error or http://b.js error.

LineNo {Number} line Number where the error occurred.

4. ColumnNo {Number} Specifies the Number of the column in which the error occurred.

Error {Object} Concrete error objects, containing more detailed error call stack information, which is very helpful in locating errors.

 

Compatibility issues

Different browsers treat the same error message differently.

In Internet Explorer 10, only message, URL, and lineNo can be obtained. ColumnNo and error cannot be obtained

However, the window.event object provides errorLine and errorCharacter, which correspond to the corresponding line and column number information.

When using onError, we can use arguments.callee.caller to recurse the call stack. This type of message is the most direct error message and must be captured and reported. Later we will use JS to demonstrate.

 

The default values are as follows:

Write a js error reporting library

Now that we know how to use window.onerror, why don't we write a js library to monitor our front-end JS?

 

Implementation idea:

Collect the five parameters of window.onerror

2. In addition to those five parameters, you can add custom parameters

3. Send it to the background server

 

Let's call our library badJsReport

 

The principle is relatively simple, the code is as follows:

/** * Name: badjsreport.js * Version 1.1.0 * Author xiangyulaodi * Address: https://github.com/xianyulaodi/badJsReport * Released on: December 22, 2016 */ ; (function(){ 'use strict'; if (window.badJsReport){ return window.badJsReport }; Reported error message * / * * the default/var defaults = {MSG: "', / / the details of the error url:" ', / / wrong url line: "', / / wrong col: ', / / errors in the error:" ', // The specific error object}; Ajax encapsulation * / * * / function ajax (options) {options = options | | {}; options.type = (options.type || "GET").toUpperCase(); options.dataType = options.dataType || "json"; var params = formatParams(options.data); if (window.XMLHttpRequest) { var xhr = new XMLHttpRequest(); } else { var xhr = new ActiveXObject('Microsoft.XMLHTTP'); } xhr.onreadystatechange = function () { if (xhr.readyState == 4) { var status = xhr.status; if (status >= 200 && status < 300) { options.success && options.success(xhr.responseText, xhr.responseXML); } else { options.fail && options.fail(status); } } } if (options.type == "GET") { xhr.open("GET", options.url + "?" + params, true); xhr.send(null); } else if (options.type == "POST") { xhr.open("POST", options.url, true); Xhr.setrequestheader (" content-type ", "application/x-www-form-urlencoded"); // Set the Content Type xhr.setrequesTheader (" content-type ", "application/x-www-form-urlencoded"); xhr.send(params); Function formatParams(data) {var arr = []; for (var name in data) { arr.push(encodeURIComponent(name) + "=" + encodeURIComponent(data[name])); } arr.push(("v=" + Math.random()).replace(".","")); return arr.join("&"); */ function cloneObj(oldObj) {// Copy object method if (typeof(oldObj)! = 'object') return oldObj; if (oldObj == null) return oldObj; var newObj = new Object(); for (var prop in oldObj) newObj[prop] = oldObj[prop]; return newObj; }; Function extendObj() {var args = arguments; if (args.length < 2) {return; } var temp = cloneObj(args[0]); For (var n= 1,len=args.length; n 0)) { ext.push(fn.toString()); if (fn === fn.caller) { break; } fn = fn.caller; } ext = ext.join(","); defaults.msg = error.stack.toString(); } / / merge report data, including the default report data and the custom reporting data var reportData = extendObj (params) data | | {}, defaults). // Send error message to background Ajax ({url: params.url, // request address type: "POST", Function (response, XML) {params.successCallback &¶ Ms. SuccessCallBack (response, XML); }, fail: function (status) {params.failcallback &¶ Ms. FailCallBack (status); }}); }, 0); return true; // The error does not appear in the console browser, so you can comment it like this if necessary}; } window.badJsReport=badJsReport; }) (); /*=========================== badJsReport AMD Export ===========================*/ if (typeof(module) ! == 'undefined'){ module.exports = window.badJsReport; } else if (typeof define === 'function' && define.amd) { define([], function () { 'use strict'; return window.badJsReport; }); }Copy the code

We encapsulate native Ajax and merge the reported parameter objects. And exposes a global method, badJsReport

 

Usage:

1. Load badjsReport.js before any other JS

2, simple usage :(this execution method should be placed before other code execution)

BadJsReport ({url:'http://www.baidu.com', // Url sent to background * must})Copy the code

3. If you need to add reporting parameters, or know the callback sent to the background. This can be done in the following way

BadJsReport ({url:'http://www.baidu.com', // The url sent to the background * must be data:{}, // add custom report parameters, such as app version, SuccessCallBack :function(response, XML){// failCallBack:function(error){// failCallBack:function(error){ - can be omitted}})Copy the code

Note:

1. For cross-domain JS resources, window.onerror does not get detailed information, so additional headers need to be added to the resource request.

Static resource requests require an access-Control-allow-Origin header, that is, an Access-Control-allow-Origin header, and a Crossorigin attribute. In this way, accurate error information can be obtained.

2. If there is an error message, the browser will not console. If you need browser console, comment out the last return true

 

Disadvantages:

For the compressed code, we get the wrong message, but we can't locate the wrong number of lines, such as jquery's source code compression, which is only 3 lines. This makes it hard to pinpoint specific places because there are many, many lines of code on one line. For more on that, check out this article by Nguyen Yifeng:

JavaScript Source Map details

 

I put the code on Github: github.com/xianyulaodi...

 

Please point out any mistakes

 

Reference article:

Build a reliable front-end exception monitoring service - collection section

JSTracker: Front-end exception data collection

Front-end code exception monitoring scheme window.onerror

 


Did this article help you? Welcome to join the front End learning Group wechat group: