preface

With the rapid development of the front-end field, the requirements for product performance are becoming higher and higher. Although the product needs to pass the self-test of r&d and the test of professional testers, there will still be some bugs in the user use stage. For these bugs, only a few users will give feedback or choose to give up using the product because of these bugs, and these bugs that appear through self-testing of r&d and testing by professional testers are difficult to reproduce. Therefore, the timely discovery and solution of bugs has become the focus of product optimization.

Common mistakes

Grammar mistakes

Syntax errors are common during development, and almost all of the modern front-end engineering code is compiled, so they are discovered and resolved during development. (Common syntax error: Write English characters as Chinese characters)

Note: Syntax errors cannot be handled by try catch

Synchronization error

When executing ascript, javascript blocks the task into the execution stack for polling out execution. Each task has its own execution context. Any error occurred in the synchronized code executed in the current execution context can be caught by try catch to ensure that the subsequent synchronized code is executed.

Asynchronous error

Common setTimeout, setInterval and other methods are executed after the execution of the previous macrotasks due to the javascript event loop mechanism, so try catch cannot catch code errors in other contexts.

In order to analyze errors, the window.onerror event is used to listen for errors. It is more powerful than try catch’s ability to catch error messages.

/ * * *@param {String}  MSG Error description *@param {String}  Url error file *@param {Number}  The row line number *@param {Number}  Col column number *@param {Object}  Error Error object */
 window.onerror = function (msg: string, url: string, row: number, col: number, error: Error) {
  console.log('I know my mistake.');
  // return true; // When true is returned, the exception will not be thrown up and the console will not print an error
};
Copy the code
  • window.onerrorMatters needing attention
    • Window. onerror can catch common syntax, synchronous, asynchronous errors, etc.
    • Window. onerror cannot catch Promise errors, network errors;
    • Window.onerror should be executed before all JS scripts to avoid omission;
    • Window.onerror is easy to overwrite and should be considered when handling callbacks because it is also being listened on by someone else.

Network error

Because network request exceptions do not bubble, they need to be retrieved during the event capture phase. We can use window.addeventListener. For example, when important CDN resources such as code and pictures fail, it is extremely important to get timely feedback.

window.addEventListener('error'.(e: Event) = > {
  // Avoid duplicate reporting
  if(target ! = =window) {
    console.log(e);
  }      
  // return true; // Interrupts event propagation
}, true);
Copy the code

Promise error

If you don’t catch a promise, then onError doesn’t do anything.

Promise.reject('promise error');
new Promise((resolve, reject) = > {
  reject('promise error');
});
new Promise((resolve) = > {
  resolve();
}).then(() = > {
  throw 'promise error';
});
Copy the code

Window.addeventlistener (“unhandledrejection”) to monitor for errors. Receive a PromiseError object that resolves the Reason property of the error object, sort of like a stack. For details, see tracekit.js [github.com/csnover/Tra…]. You can see that.

In actual combat

The front-end code

import TraceKit from 'tracekit';
import {createWebPageError, createWebPageResourceError} from ".. /.. /.. /service/monitor";

export default class ErrorMonitor {
    private static instance: ErrorMonitor;

    static getInstance(): ErrorMonitor {
        Instance is returned directly if it is an instance, if it is not instantiated
        if(! ErrorMonitor.instance) { ErrorMonitor.instance =new ErrorMonitor()
        }
        return ErrorMonitor.instance
    }

    constructor() {
        ErrorMonitor.init();
    }

    /** * Common syntax, synchronous, asynchronous errors and other error callback *@param message
     * @param url
     * @param lineNum
     * @param columnNum
     * @param error* /
    protected static windowErrorHandle(message: string.url: string.lineNum: number.columnNum: number.error: Error) :boolean {
        /* eslint-disable */
        const {location: {href}} = window;
        createWebPageError({href, message,  url,  lineNum, columnNum, error: JSON.stringify(error, ['message'.'stack'])});
        /* eslint-disable */
        return true;
    };

    /** * Resource loading error callback *@param e* /
    protected static networkErrorHandle(e: Event) {
        const target = e.target || e.srcElement;
        if(target ! = =window) {
            const {location: {href}} = window;
            const {src} = target as any; createWebPageResourceError({href, src}); }}/** * Promise error callback *@param e* /
    protected static promiseErrorHandle(e: ErrorEvent) {
        e.preventDefault();
        TraceKit.report((e as any).reason);
        return true;
    }



    protected static bindEvent() {
        window.onerror = ErrorMonitor.windowErrorHandle;
        window.addEventListener('error', ErrorMonitor.networkErrorHandle, true);
        window.addEventListener('unhandledrejection', ErrorMonitor.promiseErrorHandle);
    }

    protected static init() {
        ErrorMonitor.bindEvent();
    };
}

Copy the code

Back-end database

CREATE TABLE IF NOT EXISTS `page_error` ( `id` int(11) NOT NULL AUTO_INCREMENT, 'userId' int(11) DEFAULT NULL COMMENT 'Inst/inST/INST/INST/inST/inST/inST/inST/inST/inST/inST/inST/inST/inST/inST/inST/inST/inST/inST/inST/inST/inST 'href' varchar(255) DEFAULT NULL COMMENT 'error ',' varchar(255) DEFAULT NULL COMMENT 'error ', 'url' varchar(255) DEFAULT NULL COMMENT '错 误 ',' lineNum 'int(11) DEFAULT NULL COMMENT' 错 误 ', 'columnNum' int(11) DEFAULT NULL COMMENT '错误 ', 'error' longtext DEFAULT NULL COMMENT '错误 ', 'createTime' TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'createTime ', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;Copy the code

The last

Front-end error monitoring Front-end developers must have the knowledge to receive error data and solve online problems in a timely manner to improve user experience.

The personal tech blog has been reconfigured using typescript + React hooks + ANTd.

Personal blog address, interested can take a look

Making the address