Home >Web Front-end >JS Tutorial >Exceptional Exception Handling in JavaScript
Core points
In software development, Murphy's law also applies: anything that can go wrong will go wrong. For non-simple programs, the question is not whether will make an error, but when will make an error. Standard incompatible, unsupported features and browser features are just a few sources of potential problems faced by web developers. Given all the problems that may arise, JavaScript has a surprisingly simple error handling method - it just gives up and fails silently. At least, this is the behavior seen by the user. In fact, a lot of things happened behind the scenes. When a JavaScript statement produces an error, it is said that it throws an
exception. The JavaScript interpreter does not continue to execute the next statement, but checks for exception handling code. If there is no exception handler, the program will return from any function that throws the exception. This will repeat each function on the call stack until the exception handler is found or the top-level function is reached, causing the program to terminate. Error object
When an exception occurs, an object representing the error is created and thrown. The JavaScript language defines seven types of built-in error objects. These error types are the basis for exception handling. Each error type is described in detail below. Error
"Error" type is used to indicate a general exception. This exception type is most commonly used to implement user-defined exceptions. The topic of creating user-defined exceptions will be revisited later in this article. The "Error" object is instantiated by calling its constructor, as shown in the following example:
When the number exceeds the specified range, a "RangeError" exception is generated. For example, JavaScript numbers have the toFixed() method, which takes the "digits" parameter to represent the number of digits that appear after the decimal point. This parameter should be between 0 and 20 (although some browsers support a wider range). If the value of "digits" is outside this range, a "RangeError" is thrown. The following example shows this.
<code class="language-javascript">var error = new Error("error message");</code>
When accessing non-existent variables, a "ReferenceError" exception will be thrown. These exceptions usually occur when there is an existing variable name that is misspelled. In the following example, a "ReferenceError" occurs when accessing "bar". Note that this example assumes that "bar" does not exist in any active scope when attempting to increment operations.
<code class="language-javascript">var pi = 3.14159; pi.toFixed(100000); // RangeError</code>
When JavaScript language rules are violated, a "SyntaxError" will be thrown. Developers familiar with languages such as C and Java are used to encountering syntax errors during compilation. However, since JavaScript is an interpreted language, syntax errors are not recognized until the code is executed. Syntax errors are unique because they are the only exception type that cannot be recovered from. The following example generates a syntax error because the "if" statement lacks the right brace.
<code class="language-javascript">function foo() { bar++; // ReferenceError }</code>
When the value is not the expected type, a "TypeError" exception occurs. Trying to call a non-existent object method is a common cause of such exceptions. The following example creates an empty object named "foo" and then tries to call its bar() method. Since bar() is not defined, a "TypeError" is thrown when trying to call it.
<code class="language-javascript">if (foo) { // SyntaxError // 缺少右花括号 }</code>
When methods such as encodeURI() and decodeURI() encounter malformed URI, a "URIError" exception will be thrown. The following example generates a "URIError" when trying to decode the string "%". The "%" character indicates the beginning of the URI escape sequence. Since there is nothing after "%" in this example, the string is an invalid escape sequence and is therefore a malformed URI component.
<code class="language-javascript">var foo = {}; foo.bar(); // TypeError</code>
When the eval() function is not used, an "EvalError" exception will be thrown. These exceptions are not used in the latest version of the EcmaScript standard. However, in order to maintain backward compatibility with older version standards, they are still supported.
Exception handling
Now that we know what exceptions are, we should learn how to prevent them from causing the program to crash. JavaScript handles exceptions through the "try…catch…finally" statement. A common example statement is shown below.
<code class="language-javascript">decodeURIComponent("%"); // URIError</code>
The first part of the "try...catch...finally" statement is the "try" clause. The "try" clause is required to separate blocks of code that programmers suspect may generate exceptions. The "try" clause must be followed by one or two "catch" and "finally" clauses.
"catch" clause
The second part of "try…catch…finally" is the "catch" clause. The "catch" clause is a block of code that is executed only when an exception occurs in the "try" clause. Although the "catch" clause is optional, it is impossible to really handle exceptions without it. This is because the "catch" clause prevents exceptions from propagating in the call stack, allowing program recovery. If an exception occurs in the "try" block, control is immediately passed to the "catch" clause. The exception that occurs is also passed to the "catch" block for processing. The following example shows how to use the "catch" clause to handle a "ReferenceError". Note that the "ReferenceError" object can be used in the "catch" clause through the "exception" variable.
<code class="language-javascript">var error = new Error("error message");</code>
Complex applications can generate various exceptions. In this case, the "instanceof" operator can be used to distinguish various types of exceptions. In the following example, it is assumed that the "try" clause can generate several types of exceptions. The corresponding "catch" clause uses "instanceof" to handle the "TypeError" and "ReferenceError" exceptions separately from all other types of errors.
<code class="language-javascript">var pi = 3.14159; pi.toFixed(100000); // RangeError</code>
"finally" clause
The last component of the "try…catch…finally" statement is the optional "finally" clause. The "finally" clause is a block of code executed after the "try" and "catch" clauses, regardless of whether an error occurs. The "finally" clause is useful for including cleaning code (closing files, etc.) that needs to be executed anyway. Note that the "finally" clause executes even if an uncaught exception occurs. In this case, the "finally" clause is executed, and the thrown exception continues normally.
An interesting note about the "finally" clause is that even if the "try" or "catch" clause executes the "return" statement, it will execute. For example, the following function returns false because the "finally" clause is the last executed content.
<code class="language-javascript">function foo() { bar++; // ReferenceError }</code>
Top an exception
JavaScript allows programmers to throw their own exceptions through statements named "throw". This concept can be a bit confusing for inexperienced developers. After all, developers struggle to write code without errors, but the "throw" statement deliberately introduces errors. However, intentionally throwing exceptions can actually make the code easier to debug and maintain. For example, by creating meaningful error messages, it is easier to identify and resolve problems.
The following shows several examples of the "throw" statement. There is no limit on the data types that can be thrown as exceptions. There is also no limit on the number of times the same data can be captured and thrown. In other words, an exception can be thrown, caught, and then thrown again.
<code class="language-javascript">if (foo) { // SyntaxError // 缺少右花括号 }</code>
While the "throw" statement can be used with any data type, using built-in exception types has some advantages. For example, Firefox specializes in these objects by adding debug information, such as file names and line numbers where exceptions occur.
For example, suppose that a division operation occurs somewhere in your application. Since there may be a situation where division by zero occurs, division can be troublesome. In JavaScript, such operations result in "NaN". This can lead to confusing results that are difficult to debug. If the app complains loudly about dividing by zero, the situation will be much simpler. The following "if" statement does this by throwing an exception.
<code class="language-javascript">var error = new Error("error message");</code>
Of course, it may be more appropriate to use "RangeError", as shown below:
<code class="language-javascript">var pi = 3.14159; pi.toFixed(100000); // RangeError</code>
Custom exception object
We just learned how to generate custom error messages using built-in exception types. However, another way is to create a new exception type by extending the existing "Error" type. Since the new type inherits from "Error", it can be used like other built-in exception types. Although this article does not discuss inheritance topics in JavaScript, a simple technique is introduced here.
The following example will return to the problem of handling the division by zero. Instead of using the "Error" or "RangeError" object as before, we want to create our own exception type. In this example, we are creating the "DivisionByZeroError" exception type. The function in the example acts as the constructor of our new type. The constructor is responsible for assigning the "name" and "message" attributes. The last two lines of the example allow the new type to inherit from the "Error" object.
<code class="language-javascript">function foo() { bar++; // ReferenceError }</code>
Things to remember
JavaScript exception handling FAQ
What is the difference between syntax errors and runtime errors in JavaScript?
On the other hand, a runtime error occurs during program execution, after successful compilation. These errors are usually caused by illegal operations performed by the code. For example, trying to access an undefined variable or calling a function that does not exist can cause a runtime error.
How to handle exceptions in JavaScript?
<code class="language-javascript">var error = new Error("error message");</code>
The "finally" block in JavaScript is used to execute code after the try and catch blocks, regardless of the result. This means that the code in the "finally" block will be executed regardless of whether the exception is thrown or not. It is usually used to clean up after the code is executed, such as closing files or clearing resources.
Yes, JavaScript allows you to throw your own exception using the "throw" statement. You can throw any type of exception, including strings, numbers, boolean values, or objects. Once an exception is thrown, the normal process of the program will be stopped and control will be passed to the most recent exception handler.
JavaScript allows you to create custom error types by extending the built-in Error object. This is useful when you want to throw a specific type of error in your code. Here is an example:
<code class="language-javascript">var pi = 3.14159; pi.toFixed(100000); // RangeError</code>
Error propagation refers to the process of passing an error up from where it was thrown to the nearest exception handler in the call stack. If no error is caught in the function that throws the error, it will be propagated upward to the calling function, and so on until it is captured or reached the global scope, at which point the program will terminate.
JavaScript provides the console.error() method to log errors. This method works the same way as console.log() , but it also contains a stack trace in the log and highlights the message as an error in the console. Here is an example:
<code class="language-javascript">function foo() { bar++; // ReferenceError }</code>
In JavaScript, both "null" and "undefined" indicate missing values. However, they are used in slightly different contexts. "Undefined" means that a variable has been declared but has not been assigned a value. "null" on the other hand is an assignment value, indicating no value or no object.
Asynchronous errors can be handled using Promise or async/await in JavaScript. Promise has a "catch" method that is called when Promise is rejected. With async/await you can use the try/catch block just like you would with synchronous code. Here is an example using async/await:
<code class="language-javascript">if (foo) { // SyntaxError // 缺少右花括号 }</code>
When the operation cannot be performed, usually when the value is not the expected type, a TypeError is thrown in JavaScript. For example, attempting to call a non-function or access an undefined property will result in a TypeError.
The above is the detailed content of Exceptional Exception Handling in JavaScript. For more information, please follow other related articles on the PHP Chinese website!