Error Handling in JavaScript

Error Handling in JavaScript

This article explains error handling in JavaScript.

YouTube Video

Error Handling in JavaScript

Error handling in JavaScript is an important feature for catching and appropriately handling errors when a program encounters unexpected issues. Primarily, it is common to use the try...catch syntax to catch and handle errors. Additionally, when dealing with Promises or asynchronous operations, error handling can also be done using async/await or Promise.prototype.catch.

try...catch Syntax

try...catch is used to catch and handle errors when they occur within a code block.

 1try {
 2    // Code that may throw an error
 3    let result = riskyFunction();
 4    console.log(result);
 5} catch (error) {
 6    // Catch and handle the error
 7    console.error("An error occurred:", error.message);
 8} finally {
 9    // Code that will always execute
10    console.log("Error handling has completed.");
11}
  • If an error occurs inside a try block, the execution of the program is interrupted, and the catch block is executed.
  • The finally block is always executed, regardless of whether there is an error or not. It is useful for releasing resources and final processing, among other things.

Throwing Errors (throw)

In JavaScript, you can explicitly trigger an error using the throw keyword. It is used when throwing custom error messages or custom errors.

 1function checkAge(age) {
 2    if (age < 18) {
 3        throw new Error("You are under 18 years old.");
 4    }
 5    return "Age verification completed.";
 6}
 7
 8try {
 9    let result = checkAge(15);
10    console.log(result);
11} catch (error) {
12    console.error(error.message);  // Displays "You are under 18 years old."
13}

Error Handling in Asynchronous Operations (Promise and async/await)

When performing asynchronous operations, error handling is slightly different. When using Promises, errors are caught with the catch method.

1let promise = new Promise((resolve, reject) => {
2    // Asynchronous operation
3    setTimeout(() => reject(new Error("An issue has occurred!")), 1000);
4});
5
6promise
7    .then(result => console.log(result))
8    .catch(error => console.error(error.message));  // Displays "An issue has occurred!"

When performing asynchronous operations using async/await, you can handle errors with try...catch.

 1async function fetchData() {
 2    try {
 3        let response = await fetch('https://api.example.com/data');
 4        let data = await response.json();
 5        console.log(data);
 6    } catch (error) {
 7        console.error("An error occurred while fetching data:", error.message);
 8    }
 9}
10
11fetchData();

Summary

  • You can catch synchronous errors using the try...catch syntax.
  • You can throw your own errors using throw.
  • Errors in asynchronous operations can be handled using the catch method of Promise, or with async/await and try...catch.

By utilizing these methods, you can ensure that your program functions correctly even when errors occur.

Error

The Error class is used for error handling. It provides the capability to create errors and supply error messages and stack traces.

1try {
2    throw new Error("Something went wrong");
3} catch (e) {
4    console.log(e.message); // Something went wrong
5}

Basic Usage

An Error object can be explicitly created when an error occurs. You create an instance with new Error() and pass an error message.

1const error = new Error("Something went wrong");
2console.log(error.message);  // "Something went wrong"
3console.log(error.name);     // "Error"
4
5// Stack trace (information about where the error occurred)
6console.log(error.stack);

Properties of the Error Object

The Error object has the following properties.

  • message: This is the error message.
  • name: The name of the error, which defaults to "Error".
  • stack: A stack trace containing where the error occurred, useful for debugging.

Throwing Errors with throw

In JavaScript, you can throw an error using the throw keyword. This is used to interrupt processing in specific situations and pass control to an error handler.

1function doSomething() {
2    throw new Error("This function is not yet implemented");
3}
4
5try {
6    doSomething();
7} catch (e) {
8    console.error(e.message);  // "This function is not yet implemented"
9}

Errors thrown with throw can be caught using the try...catch syntax.

Creating Custom Errors

In JavaScript, you can create your own custom errors by extending the Error class. This allows you to create errors tailored to specific situations.

 1class CustomError extends Error {
 2    constructor(message) {
 3        super(message);  // Call the parent class constructor
 4        this.name = "CustomError";  // Set the error name
 5    }
 6}
 7
 8try {
 9    throw new CustomError("A custom error has occurred");
10} catch (e) {
11    console.error(e.name);    // "CustomError"
12    console.error(e.message); // "A custom error has occurred"
13}

Built-in Error Classes

JavaScript has several built-in error classes that extend the Error class. These are used to represent specific errors.

  • ReferenceError: Occurs when you reference a variable that doesn't exist.
  • TypeError: Occurs when a value's type is different from the expected type.
  • RangeError: Occurs when a number is outside the allowable range.
  • SyntaxError: Occurs when code that is not syntactically correct is executed.
  • EvalError: Errors related to the use of the eval() function. It is rarely used nowadays.
  • URIError: Occurs when an invalid URI (encoding or decoding errors) is used.
Example: ReferenceError

Here is an example of a ReferenceError.

1try {
2    console.log(undefinedVariable);  // Undefined variable
3} catch (e) {
4    console.error(e.name);    // "ReferenceError"
5    console.error(e.message); // "undefinedVariable is not defined"
6}
Example: TypeError

Here is an example of a TypeError.

1try {
2    null.f();  // Attempting to call a function on null
3} catch (e) {
4    console.error(e.name);    // "TypeError"
5    console.error(e.message); // "Cannot read properties of null (reading 'f')"
6}

finally Block

In try...catch syntax, use the finally block for operations you want to execute regardless of whether an error occurs.

1try {
2    throw new Error("An issue has occurred");
3} catch (e) {
4    console.error(e.message);  // "An issue has occurred"
5} finally {
6    console.log("Performing cleanup");
7}

In this example, the operations in the finally block are executed even if an error is thrown.

Benefits of Exception Handling

By implementing error handling correctly, you can prevent the application from crashing when unexpected behavior occurs. By appropriately using the try...catch syntax and error objects, you can write more robust code.

 1function divide(a, b) {
 2    if (b === 0) {
 3        throw new Error("Cannot divide by zero");
 4    }
 5    return a / b;
 6}
 7
 8try {
 9    console.log(divide(4, 0));  // An error will occur
10} catch (e) {
11    console.error(e.message);   // "Cannot divide by zero"
12}

Summary

  • The Error class is used to represent an error cause and to perform error handling.
  • Use the try...catch...finally syntax to handle errors and prevent unexpected application termination.
  • It is also possible to extend the Error class to create custom errors.
  • You can handle various types of errors by using built-in error classes like TypeError and ReferenceError.

You can follow along with the above article using Visual Studio Code on our YouTube channel. Please also check out the YouTube channel.

YouTube Video