Known errors and unknown errors
Errors can be divided into known errors and unknown errors. Known errors refer to the errors that can be analyzed by the code, such as the wrong type of parameter being passed. Such errors can be handled directly, such as adding type verification. It is unknown errors that require error handling, since no one can guarantee that their code is error-free. Even if there were, there’s always a chance that someone else’s package could go wrong. For unknown errors, we need to reduce the occurrence of errors, and we need to set up an error handling mechanism to handle the errors that occur.
How can errors be reduced
- Use static code profilers, such as TypeScript (to avoid data type errors).
- With strict equality and strict inequality only, except when checking whether a variable is not null and not undefined (after all, this is how the jQuery source code is written), you can write:
if (abc ! = null) { ... }Copy the code
- Use non-Booleans in flow control statements such as if, for, or while; in short, use implicit conversions as little as possible.
- Use encodeURIComponent() for parameter parts when concatenating urls
function addQueryStringArg(url:string, name:string, value:string) :string {
const suffix = url.includes('? ')?'&':'? ';
const encodeName = encodeURIComponent(name);
const encodeValue = encodeURIComponent(value);
return `${url}${suffix}${encodeName}=${encodeValue}`;
}
Copy the code
Establish an error handling mechanism
There is a lot of error-handling code in the Vue source code, and we can often see clearly what is wrong from these errors and fix it quickly. It is more intuitive to throw a clear error than to throw an obscure error by the browser, so it is necessary to build an error handling mechanism on the front end. To build this mechanism, we need to do three things:
- Capture the error
- Provide concise and easy-to-understand tips
- Record errors and reduce the occurrence of errors
/ / the vue source code
// src/platforms/web/entry-runtime-with-compiler.js 36:58
if (template) {
if (typeof template === 'string') {
if (template.charAt(0) = = =The '#') {
template = idToTemplate(template)
/* istanbul ignore if */
if(process.env.NODE_ENV ! = ='production' && !template) {
warn(
`Template element not found or is empty: ${options.template}`.this)}}}else if (template.nodeType) {
template = template.innerHTML
} else {
if(process.env.NODE_ENV ! = ='production') {
warn('invalid template option:' + template, this)}return this}}else if (el) {
template = getOuterHTML(el)
}
Copy the code
Capture the error
We usually use try/catch statements to catch errors. Here are a few things to note:
- The optional finally clause ina try/catch statement is always run. Even if you write a return ina try or catch block, if the code contains a finally clause, the return statement in the try or catch block is ignored.
- Only one of the finally clause and catch block is required.
- In the catch block of a try/catch statement, you can use the instanceof operator to determine the type of error.
Ecma-262 defines the following eight error types:
The serial number | type | note |
---|---|---|
1 | Error | Base class from which other error types inherit, typically custom errors thrown by developers |
2 | InternalError | Internal error |
3 | EvalError | Basically, this error is reported as long as eval() is not considered a function call |
4 | RangeError | Is thrown if the value is out of bounds |
5 | ReferenceError | Will be thrown if the object cannot be found |
6 | SyntaxError | Grammar mistakes |
7 | TypeError | Type error |
8 | URIError | Occurs only when encodeURI() or decodeURI() is used but an ill-formed URI is passed in |
It is obvious that try/catch statements are only good for catching local errors, and that if you want to listen for global errors, you should obviously use the window error event. Any error that is not handled by a try/catch statement raises an error event on the window. (This event was an early browser support, and many browsers kept its format unchanged for backward compatibility.)
Note that only synchronous errors are caught here; asynchronous errors of promises need to be handled with catch() unless the promise is preceded by await.
window.onerror = (message/* Error message */, url/* Error url*/, line/ * * /) = > {
To ensure cross-browser compatibility, it is best to rely only on the message attribute.
console.log(message);
return false; // Can return false to prevent the browser from reporting errors by default
};
Copy the code
Provide concise and easy-to-understand tips
To ensure a succinct and easy-to-understand hint, we can throw a custom exception through a throw. The throw operator must have a value, but the value type is unlimited.
throw new Error('Wrong! ');
Copy the code
You can also create custom Error types by integrating Error. To create a custom error type, you need to provide the name and message attributes, such as:
class CustomError extends Error {
constructor (message) {
super(message);
this.name = 'CustomError';
this.message = message; }}throw new CustomError('My message');
Copy the code
The constructor for each error type takes only one argument, the error message. Custom Error types that integrate Error are treated by browsers as other built-in Error types. Custom error types help to distinguish errors more accurately when they are caught.
Record errors and reduce the occurrence of errors
A common practice in Web application development is to set up a centralized error log store and trace system. To log errors on all pages, the above code can be rewritten as:
function logError(sev, msg) {
let img = new Image();
let encodeSev = encodeURIComponent(sev);
let encodeMsg = encodeURIComponent(msg);
img.src = `log.php? sev=${encodeSev}&msg=${encodeMsg}`;
}
window.onerror = (message/* Error message */, url/* Error url*/, line/ * * /) = > {
To ensure cross-browser compatibility, it is best to rely only on the message attribute.
logError(url, message);
return false; // Can return false to prevent the browser from reporting errors by default
};
Copy the code
By recording error messages, we can know what errors were reported and how wide their impact was, so that we can know what errors need to be removed.
(Appendix) Debugging technology
methods | note |
---|---|
console.log() | Logging regular messages |
console.info() | Log message content |
console.error() | Logging error messages |
console.warn() | Record warning messages |
debugger | Used for breaking points |
A combination of debugger and console.log() is commonly used when fixing bugs. | |
Tip: After checking an element, or clicking on an element in Elements in the developer tool, you can reference a JavaScript instance of that node in the console with $0. |