During development, our goal is 0error, 0warning.
But there are many factors beyond our control, and to avoid errors in one piece of code that affect other modules or the overall code, we often use the try-catch
module to actively catch some exceptions or errors.
For example, if we get the parameters in the url and parse them in JSON, we need to wrap them in try-catch
because we can’t guarantee that the parameters we get will be parsed properly.
It is possible that the user may intentionally or unintentionally copy the link incompletely, resulting in an incomplete parameter. JSON.parse
cannot parse incomplete json string.
To avoid JSON parsing errors caused by incomplete data, we can include it with try-catch
.
1. What errors can’t be caught by try-catch
We often use the try-catch
module to actively catch some exceptions or errors, so that this block of code does not affect other modules or the overall code. But there are some cases where try-catch does not catch an exception in the code!
1.1 Cross-domain errors
When we use xhr to request an interface, the browser will prompt an error in the console if the interface does not support cross-domain.
|
|
As we can see in the image, the request for the interface is generating a cross domain error, but it’s not going to catch
.
Previously, when I was doing canvas compositing, the domain name of some images did not support cross-domain, so I wanted to request the image directly first, and if the image was cross-domain, then request the backend interface, which would convert the image to base64, but in the process of testing, I found that this cross-domain error would definitely be shown. However, I didn’t want to show it to the caller in the first place, because I had already set up a tuck-in solution. But you can’t trot out the error with try-catch.
Of course, this doesn’t mean that the front-end doesn’t know that a cross-domain error was generated. We can know that the xhr request generated a request error by listening to xhr.onerror.
1.2 Asynchronous errors
If an error is generated by an asynchronous module in try, catch will not catch it, for example.
|
|
As you can see by the runtime results in the image, both of these codes, do not go into the catch module.
So how should we catch this asynchronous error? The answer is to put the try-catch inside the asynchronous code.
|
|
One great advantage of Promise is that it comes with an exception catch method catch()
that automatically goes to the catch() method when the then() method generates an error that prevents the code from running. So it is recommended to write Promise with catch() on it, otherwise uncaught exceptions will bubble up to the global level.
1.3 How to catch exceptions in async-await
The syntactic sugar of async-await
allows us to write Promise like synchronous code, so how do we catch exceptions in async-await?
Here we would normally use try-catch
to catch exceptions.
When the somethingThatReturnsAPromise() method throws a reject exception, it will be caught by catch.
Of course, async-await has another way of catching exceptions, by returning the correct data via await and writing catch()
along with it, so that when the somethingThatReturnsAPromise() method throws an exception, it will automatically go to the catch() method.
However, after this catching of the exception, the catch() method of the outer layer does not catch the exception and does not continue to bubble up to the outer layer. The correct approach is that errors generated by the underlying module should be thrown directly to the business layer to let the business layer decide what to do with the error, rather than just swallowing it.
1.4 Multi-layer try-catch
When multi-layer try-catch is used, it is caught by the innermost catch() method, and then it stops bubbling to the outer layer.
Next, we understand the types of errors that occur in js.
2. Native error types
Before we get into using try-catch
, let’s understand what are the native error types in js.
There are six types of errors that can be generated by js code at runtime.
- SyntaxError.
- TypeError.
- rangeError.
- evalError.
- ReferenceError.
- URI error.
These error types all inherit from the Error
class.
2.1 SyntaxError
Syntax error, usually the developer in the development process, the code statement is written in a problem, the browser can not parse it.
2.2 TypeError
Type errors usually occur in two cases.
- the operator is used on an improperly typed variable, such as a concat operation on a numeric type.
- The operated variable encounters an unanticipated null or undefined value.
When writing methods to be called by other modules, a TypeError
error can be thrown when checking for vacant parameters such as null or null.
2.3 RangeError
This error is usually caused by passing in parameters that are out of the specified range. For example, the toFixed()
method can accept values in the range 0-100, and when this range is exceeded, the error is thrown.
|
|
2.4 evalError
This type of error is generally rarely encountered, because other types of errors are thrown when using eval operations, even if they are not justified.
2.5 ReferenceError
A reference error indicates that the master or apprentice is accessing an undeclared variable.
|
|
2.6 URI errors (URIError)
This error is usually thrown by some manipulation of uri functions, mainly: encodeURI(), decodeURI(), encodeURIComponent(), decodeURIComponent(), escape(), unescape().
3. Customizing error types
For slightly larger modules, we want to customize some error types by which we can tell that a module is throwing an error. How should we write this?
Our custom error types are also inherited from the Error
class, which is very simple to implement.
|
|
4. Summary
There are many ways to generate errors in the front end, and we should pay attention to avoid them. Next, we can also analyze how to monitor the errors and types of errors that occur in the page from the perspective of error monitoring.