preface

A common practice in developing Web applications is to keep a centralized error log to find the cause of important errors. Just as databases and servers regularly log, in complex Web applications we also recommend that you write JavaScript errors back to the server. In other words, we can write these errors to a place where server-side errors are stored, just to mark them as coming from the front end. In this way, the front-end errors are concentrated and the front-end developers can analyze the code conveniently.

Specific operation

The main idea

The backend needs to provide an interface to receive error messages and store them in a log file, such as font-msg.log. The front end catches errors with try{}catch(err){} statements, and then sends the collected error information to the logging interface provided by the back end through some method that can send requests. In this way, the front-end error log is available, which developers can often go to view, analyze their own code deficiencies, optimize and improve the code.

Code sample

Front-end code examples

In the front-end code, we use the Image object to send the request, which is very flexible for the following reasons:

  • Image objects are supported by all browsers;
  • To avoid cross-domain restrictions,img’s SRC attribute allows cross-domain access.
  • The probability of problems in recording errors is low.
<! < HTML lang="en"> <head> <meta charset="UTF-8"> <title> <meta name="viewport" The content = "width = device - width, initial - scale = 1.0, the minimum - scale = 1.0, maximum - scale = 1.0, User-scalable =no"/> </head> <body> <div> </body> <script> msg) { var img = new Image(); . Img SRC = "http://127.0.0.1:4000/postMessage? sev=" + encodeURIComponent(sev) + "&msg=" + encodeURIComponent(msg); } try { for(var i = 0, len= mods.length; i < len; i++) { mods[i].init(); }} catch(ex) {logError(" fatal", "Module init failed: "+ ex.message); } </script> </html>Copy the code

A friend in the comments suggested using window.onerror, which is explained in the advanced JavaScript Programming (3rd edition) book:

Any error that is not handled by a try-catch raises an error event in the Window object. In any Web browser, the onError event handler does not create an event object, but it accepts three parameters: the error message, the URL of the error, and the line number. Most of the time, only error messages are useful, because the URL only gives the location of the document, and the line number refers to code that can come from either internal JavaScript code or an external file.


An error event is raised whenever an error occurs, whether generated by the browser or not

window.onerror = function (message, url, line) {
    alert(message);
    return false;
}Copy the code

By returning false, this function effectively acts as a try-catch statement for the entire document, catching any runtime errors that are not handled by code. But the browser in the use of this event handling errors are obviously different, in IE, even if the onerror event, the code will still be normal execution, all variables and data will be preserved, so can access them in the onerror event handler, but in firefox, regular code will stop execution, before the incident Variables and data will be destroyed, so errors are almost impossible to determine, and the window.onError event will not catch the promise’s exception error message.


So I’m using try… catch… , but I think the specific use method can be determined according to their own business needs, I just do an example here, there are many practical ways to achieve, but all the same.

Back-end code examples

Here I use Node to write a log collection interface and write the collected information to the log file.

App.js (main entry file):

const Koa = require("koa");
const app = new Koa();

const router = require('./router');
const axios = require('axios')

app.use(router.routes());
app.use(router.allowedMethods());

app.on("error", function (err, ctx) {
    console.log(err)
})
app.listen(4000, function (ctx) {
    console.log("i am listening"); 
})
Copy the code

Router /index.js(route entry file):

const koaRouter = require("koa-router");
const router = new koaRouter();

const log4js = require("log4js");
var config = {
    "replaceConsole": true,
    "appenders": {
        "stdout": { 
            "type": "stdout"
        },
        "req": {
            "type": "dateFile",
            "filename": "logs/reqlog/",
            "pattern": "req-yyyy-MM-dd.log",
            "alwaysIncludePattern": true
        },
        "err": {
            "type": "dateFile",
            "filename": "logs/errlog/",
            "pattern": "err-yyyy-MM-dd.log",
            "alwaysIncludePattern": true
        },
        "oth": {
            "type": "dateFile",
            "filename": "logs/othlog/",
            "pattern": "oth-yyyy-MM-dd.log",
            "alwaysIncludePattern": true
        }
    },
    "categories": {
        "default": { 
            "appenders": ["stdout", "req"], 
            "level": "debug"
        },
        "err": { 
            "appenders": ["stdout", "err"], 
            "level": "error"
        },
        "oth": { 
            "appenders": ["stdout", "oth"], 
            "level": "info"
        }
    }
}
log4js.configure(config);
const reqLogger = log4js.getLogger();
const errLogger = log4js.getLogger('err');
const infoLogger = log4js.getLogger('oth');

router.get("/postMessage", async(ctx, next) => {
    console.log(ctx.query); 
    infoLogger.info(ctx.query.sev + "--" + ctx.query.msg);
    ctx.body = {
        msg: "i get it",
        code: 200
    };
    return next();
})
module.exports = router;
Copy the code

Screenshot of the collected log information:

More detailed code: github.com/muzishuiji….

Recommended reading:

  • <<JavaScript Advanced Programming (3rd Edition)>>
  • Talk about front-end exception catching and reporting
  • The introduction of Sentry recommended by our friends in the comments section

Do you know how the front end error message? If you have better collection method, please email([email protected]) or send me a private message, you love to share the most cute ^_^ _ ^_^

If there is any inadequacy in my article, welcome to criticize and correct ~~