Exception capture is one of the tracking methods to improve the software quality. The common way is to record the log, analyze the exception problem from the log and then follow up. For front-end projects, exceptions may be caused by back-end interface data or front-end business logic problems. No matter what the exceptions are, they can be analyzed as long as they can be accurately captured. Some people may say that there is a testing phase and a comprehensive testing mechanism does reduce the occurrence of exceptions, but most of the testing is done on non-production environments and has limited coverage.
Log is the best way to collect exceptions, an exception monitoring platform needs to include exception collection, exception storage, exception statistics and analysis, exception report, exception alarm, and for a general platform, it needs project management, version management, team management, warehouse management and so on. This article focuses on the issues to consider for exception collection and shares two off-the-shelf solutions.
Abnormal introduction
Exceptions are a structure that every programming language needs to consider. How to track exceptions in a friendly way without affecting the business on the production environment requires a certain specification of the whole process from project development to launch. Let’s talk about exceptions and handling on the front end.
Abnormal classification
The ECMA-262 defines seven error types, described as follows:
Error: a common exception, usually used with throw and try/catch statements. The name property allows you to declare or learn the type of the exception, and the message property allows you to set and read the details of the exception.
EvalError: The Eval function is abnormal.
SyntaxError: Syntax parsing is not reasonable.
RangeError: thrown when a number is out of the legal range, such as when an array index is out of bounds.
ReferenceError: thrown when reading a variable that does not exist, such as when the variable a is not defined and is then used.
TypeError: This exception is thrown when the type of a value is incorrect, such as when the parameters passed to a function are not as expected.
URIError: An error resulting from using the global URI handler in the wrong way
Exception handling
The front-end catch exception is divided into global catch and single point catch. Global capture code set, easy to manage; As a supplement, single point capture captures some special cases, but it is scattered, not good for management and easy to miss. In the process of project development, define an error catching module, all the exceptions (global exceptions and single point exceptions) of the project to the fault module for unified processing, which requires the project convention.
try-catch
The try-catch statement is a standard way of handling exceptions in JavaScript. The basic syntax is as follows:
Try {} catch (error) {// Error handling}Copy the code
An error occurs in the code in the try block, which immediately exits the code execution process and then executes the catch block. The catch block receives an object containing an error message. This is usually error.message.
finally
Finally is optional in try-catch statements; if the finally clause has been used, its code executes anyway. Whatever code is contained ina try or catch block — or even a return statement — does not prevent the finally clause from executing. Return statements in either try or catch blocks are ignored as long as the code contains a finally clause. Therefore, before you use the finally clause, be very clear about what you want your code to do. Look at this function:
const errorHelper = () => { try { return devpoint; } catch (error) { return "error"; } finally {return "I execute with or without error!" ; }}; console.log(errorHelper()); // The function itself generates an exception, but prints the result: I executed with or without an error!Copy the code
The above function code actually has an exception, because the variable devpoint is not defined, but finally executes the finally clause output, error or no error, I execute! .
throw
The throw operator, which matches the try-catch statement, is used at any time to actively throw a defined error.
const errorHelper = () => { try { return devpoint; } catch (error) { return "error"; } finally {throw new Error(" Devpoint variable undefined "); }}; console.log(errorHelper());Copy the code
window.onerror
Window. onError is a global exception catch, for a single point of exception can not catch the exception to here.
Abnormal collection
Exceptions are triggered for many reasons. For better analysis, in addition to catching the error information of the program, it is also necessary to collect the external environment of executing the program. For front-end projects, The external environment includes the system (Windows, IOS, Android) and system version, the browser (Chrome, IE, Firefox, etc.) and version, IP address, user information, running pages, network environment, AND API interface data. For this information, you need to design the log structure for collection.
Note the following rules when collecting exception logs: Collecting logs does not affect user experience or application performance.
Here is a reference to the log structure:
projectId
: Project InformationeventId
: Event ID, which is the unique identifier of a logstack
: Indicates an error stack informationrequestId
: exception flag defined by the developerlevel
: Specifies the exception level. The value can be ERROR, INFO, or WARNbrowser
: Browser informationdevice
: Device informationos
: Information about the operating systemrelease
: Indicates the application versionurl
: URL of the exception triggering pageuser
: User information, which can be an iP addresscreateAt
: Time when an exception occursnetwork
: Network informationeventKey
: Triggers the keydataRes
: API response datascreenWidth
: Screen widthscreenHeight
: Screen heightmessage
: Details about the exception
Exception reporting
How to report abnormal data collected? In other words, exception logs need to be collected and stored in the cloud for follow-up analysis of project development. One way is to directly report the exception logs asynchronously through API. Even though more information is captured, network requests will still be occupied and the application itself will be affected. Consider storing the collected exception logs locally. The best choice is IndexedDB, which has a large capacity, supports asynchronous operations, and allows customized queries.
IndexedDB is a form of offline storage on the WEB, so the storage is only temporary, and a synchronization mechanism needs to be designed to synchronize logs stored locally to the cloud server. For better synchronization, you need to design a staging area and an archive area. The newly generated logs are stored in the staging area and the successfully synchronized logs are stored in the archive area. With local storage, the synchronization process is synchronized in batches.
For backend storage, consider LevelDB, which basically beats mongodb and SQLite in terms of performance.
LevelDB is an ultra-high performance kv storage engine developed by Google. It stands out among lightweight nosql databases with its amazing read performance and even more amazing write performance. This open source project is currently a C++ library that supports the persistence storage of Key Value data at a billion-level scale. In excellent performance for the memory footprint is very small, a large amount of data is stored directly on the disk, can be understood as space for time.
Third party platform
With a brief introduction to the key points of implementing an exception monitoring platform, I’d like to share with you two tools that can be used for front-end exception tracking: Google Analytics and Sentry.
Google Analytics
Yes, Google Analytics is generally thought of as a statistical analysis of web traffic. You can track exceptions using Google Analytics event statistics. Here’s a simple way to do this:
function postEvents(error) {
var category = error.level || "warn",
action = error.action || "",
label = error.message || "";
ga("send", "event", category, action, label);
}
Copy the code
The disadvantages are that it is not easy to determine the environment conditions that triggered the exception, the version cannot be traced later, and so on.
Sentry
Sentry is a real-time event logging and aggregation platform. It is designed to monitor errors and extract all the information needed to perform appropriate post-action without any of the hassle of using standard user feedback loops.
This is a professional exception monitoring tool, basically support all the mainstream programming languages, here is just a brief introduction to the use of a front end.
First, add the following script to the page:
< script SRC = "https://cdn.ravenjs.com/3.20.1/raven.min.js" crossorigin = "anonymous" > < / script > < script type="text/javascript"> try { if ((typeof Raven) ! = "undefined"){ Raven.config('https://[email protected]/248888',{ release: 'release_0.0.5', allowSecretKey: true}).install()}} Catch (error) {} </script>Copy the code
Then you can write a unified entry in your project:
function ExceptionJs() { const ravenJs = typeof Raven ! = "undefined" ? Raven : {}; this.capture = function (error) { try { if (! (error instanceof Error)) { if (typeof error === "object") { error = JSON.stringify(error); } } if (typeof ravenJs.captureException === "function") { ravenJs.captureException(error); }} catch (e) {// This is to ensure that the exception tracing script fails and does not affect the application}}; }Copy the code
Add the following code where needed:
const exceptionHelper = new ExceptionJs(),
try {
} catch (error) {
exceptionHelper.capture(error);
}
Copy the code
Now take a look at the collected exception information:
The following is the exception statistics
Exception list
Exception details
The Sentry tool also provides the exception tracing processing function, interested partners can try to experience.