• February 28, 2024

How to search for bugs on the frontend: 4 main stages

On the frontend, the JS code is executed in the browser. JavaScript is not a compiled language, so there is always a possibility of execution errors when using the program directly. An execution error blocks the code located after the error location, and program users risk being left with a non-functional application screen that can only be restarted or closed. But there are methods for detecting errors and their safe maintenance, allowing you to avoid such situations.

  1. JavaScript language tools

Try/catch blocks

Functions that may fail are wrapped in try/catch blocks. First, the program tries to execute the code in the try block. If for some reason the code execution has broken, the program goes to the catch block, where three parameters are available:

name — standardized error name;
message — a message about the details of the error;
stack — the current stack of the call where the error occurred.

For the developer, the main thing is that the program will be able to continue execution after the catch block. Thus, the interaction with the user will not be interrupted.

Using the try/catch block, you can also call your own errors, for example, when checking data:

Sometimes they use the try/finally statement (without catch) to be able to continue using the code without handling specific errors.

Window.onerror event

It is often useful to know that the script on the page has broken, even if the program has broken and the user session has ended unsuccessfully. Usually this information is then used in error logging systems.

The global window object has an onerror event (you need to use it carefully: the implementation may differ in different browsers!):

window.onerror = function(message, url, line, col, error) {

console.log(${message}\n In ${line}:${col} on ${url});

};

If you place this code at the beginning of the script or load it with a separate script in the first place, then with any error below, detailed information about it will be available to the developer.

However, the full information is only available for scripts that were downloaded from the same domain. If the broken script is loaded from another domain, window.onerror will work, but there will be no details of the error.

Framework Components

Some JS frameworks (React, Vue) offer their own solutions for error handling. For example, React will be able to draw a special layout in place of the block where the error occurred:

In fact, the React component turns into a special component that handles errors. This is similar to wrapping functions using the try/catch construct.

  1. Project build tools

Modern JS scripts, as a rule, are made transpilable. That is, the development is carried out using the latest ES standards. And then the developer’s code is converted using a project builder (such as Webpack) into code that is guaranteed to work in a selected number of browsers.

At the assembly stage, the code is checked for syntax correctness. An unclosed bracket or an incorrect designation of the class field will immediately cause an error during assembly, and the bundle will simply not assemble. The developer will have to fix such errors right away in order to continue working.

Also, the collector may suggest that some pieces of code are not used when executing the program. Perhaps this will prompt the developer to think about a deeper study of the code, which may indirectly affect the identification of new errors.

  1. Testing

Another way to prevent errors in the code is to test it. The frontend has tools for effective use of unit tests. Frameworks such as Jest, Karma, Mocha, Jasmine are usually used. Along with test frameworks, extensions such as Enzyme, React Testing Library, Sinon and others are often used, which allow you to enrich tests with the help of mocking, spy functions and other tools.

When searching for errors, tests are primarily useful with a load of various data that can lead to execution errors. So, the following code will pass syntax validation and work as expected:

Often such errors occur when receiving data from the server (for example, by an AJAX request) with their subsequent parsing. Code testing allows you to identify and eliminate cases in advance when the code may break during execution in the client’s browser.

  1. Logging

Let’s say we have taken all possible measures to prevent errors during the development and assembly of the project. However, errors can still get into productive code. We need to somehow find out about their presence and take prompt corrective measures. Asking users to open the browser console and take screenshots is not the best option. Therefore, it is a good idea to connect error logging to the project.

The meaning is simple: for each window.onerror event or for each transition of code execution to the catch block, a simple AJAX request is made to a specially allocated server address, in the body of which error information is placed. Next, you will need a tool that will quickly notify technical support and developers about the presence of new errors and will allow you to work effectively with them. The most popular of these tools for the frontend is Sentry.

The Sentry logging system allows you to collect, group, and present errors in real time. There are builds for different languages, including JavaScript. The project provides paid access with advanced business opportunities, but you can try its main features on a free test account.

You can connect Sentry both directly in an HTML file and in components made on one of the popular frameworks: React, Vue, Angular, Ember and others.

To enable logging capabilities directly in the browser, download the script in the section:

All. If and when an error occurs in the code below this line, Sentry will log it. Logs will be recorded even when an error occurred due to scripts from other domains:

Sentry has extensive capabilities for analyzing an array of error messages and configuring notifications. It is also possible to group error logs by releases of your product:

Using Sentry, you can pass the context of the error to statistics, for example, information about the client, fingerprint, error level (fatal, error, warning, info, debug), and put tags.

It is possible to record user events in statistics. For example, you can put a change in the size of the browser window or an AJAX request on tracking. Sentry also has its own widget with a feedback window that can be shown to the user in case of an error. This will provide additional information to investigate the circumstances of the error.

To deploy Sentry together with frameworks, it is enough to simply install the package and connect: