Instagram
youtube
Facebook
Twitter

Error Handling

In this lesson, we will explore Error Handling in JavaScript, a crucial aspect of programming that allows developers to manage unexpected situations or errors that may occur during code execution. Proper error handling ensures that your application behaves gracefully, providing users with meaningful feedback and preventing crashes.


1. Understanding Errors in JavaScript

Errors in JavaScript can occur for various reasons, such as syntax errors, runtime errors, or logical errors. Understanding the types of errors and how to handle them is essential for writing robust applications.

1.1 Types of Errors

  1. Syntax Errors: These occur when the code is not written correctly according to the language syntax. They are detected during the parsing phase before execution.

    • Example: Missing parentheses, incorrect variable declarations.
  2. Runtime Errors: These occur while the program is running, often due to unexpected conditions or invalid operations.

    • Example: Trying to access a property of undefined.
  3. Logical Errors: These are mistakes in the code logic that lead to incorrect results but do not produce errors or exceptions.

    • Example: Incorrect calculations or conditions.

2. The try...catch Statement

JavaScript provides the try...catch statement to handle exceptions gracefully. This construct allows you to attempt to execute a block of code (try) and catch any errors that occur during its execution (catch).

2.1 Syntax

try {
    // Code that may throw an error
} catch (error) {
    // Code to handle the error
}

2.2 Example

try {
    let result = riskyFunction(); // A function that might throw an error
    console.log(result);
} catch (error) {
    console.error("An error occurred:", error.message);
}

In this example, if riskyFunction throws an error, it will be caught by the catch block, and the error message will be logged to the console.


3. The finally Block

The finally block can be added to a try...catch statement and will execute regardless of whether an error was thrown or caught. This is useful for cleanup actions, such as closing database connections or freeing resources.

3.1 Syntax

try {
    // Code that may throw an error
} catch (error) {
    // Code to handle the error
} finally {
    // Code that will always execute
}

3.2 Example

try {
    let data = JSON.parse('{"invalidJson":}');
} catch (error) {
    console.error("JSON parsing error:", error.message);
} finally {
    console.log("Execution completed."); // This will always run
}

4. Throwing Custom Errors

You can create and throw custom errors using the throw statement. This is useful for indicating specific error conditions in your application.

4.1 Syntax

throw new Error("Custom error message");

4.2 Example

function validateAge(age) {
    if (age < 0) {
        throw new Error("Age cannot be negative.");
    }
    return age;
}

try {
    validateAge(-5);
} catch (error) {
    console.error("Validation error:", error.message); // Outputs: Validation error: Age cannot be negative.
}

5. Promises and Error Handling

When working with Promises, you can handle errors using the .catch() method or by using try/catch blocks in an async function.

5.1 Using .catch() with Promises

let myPromise = new Promise((resolve, reject) => {
    let success = false;
    if (success) {
        resolve("Operation succeeded!");
    } else {
        reject("Operation failed!");
    }
});

myPromise
    .then(result => {
        console.log(result);
    })
    .catch(error => {
        console.error("Promise error:", error);
    });

5.2 Using try/catch with Async/Await

async function fetchData() {
    try {
        let response = await fetch("https://jsonplaceholder.typicode.com/posts/1");
        if (!response.ok) {
            throw new Error("Network response was not ok");
        }
        let data = await response.json();
        console.log(data);
    } catch (error) {
        console.error("Fetch error:", error.message);
    }
}

fetchData();

6. Practical Exercises

Create a JavaScript file named errorHandlingPractice.js and complete the following exercises:

  1. Basic Error Handling: Write a function that divides two numbers and throws an error if the divisor is zero. Handle the error appropriately using try/catch.

  2. Promise Error Handling: Create a Promise that simulates a network request. Reject the Promise with an error if the request fails, and handle the error using .catch().

  3. Async/Await Error Handling: Write an async function that fetches data from an API. Use try/catch to handle any errors that may occur during the fetch operation.

Example Solutions:

// 1. Basic Error Handling
function divide(a, b) {
    if (b === 0) {
        throw new Error("Division by zero is not allowed.");
    }
    return a / b;
}

try {
    console.log(divide(10, 0));
} catch (error) {
    console.error("Error:", error.message); // Outputs: Error: Division by zero is not allowed.
}

// 2. Promise Error Handling
let fetchData = new Promise((resolve, reject) => {
    let success = false; // Simulate a failed request
    if (success) {
        resolve("Data fetched successfully!");
    } else {
        reject("Failed to fetch data.");
    }
});

fetchData
    .then(result => {
        console.log(result);
    })
    .catch(error => {
        console.error("Promise error:", error); // Outputs: Promise error: Failed to fetch data.
    });

// 3. Async/Await Error Handling
async function getPost(postId) {
    try {
        let response = await fetch(`https://jsonplaceholder.typicode.com/posts/${postId}`);
        if (!response.ok) {
            throw new Error("Post not found.");
        }
        let post = await response.json();
        console.log(post);
    } catch (error) {
        console.error("Fetch error:", error.message); // Outputs: Fetch error: Post not found. (if invalid ID)
    }
}

getPost(100); // Test with an invalid ID

Conclusion

In this lesson, we covered the fundamentals of error handling in JavaScript, including the use of try...catch, custom errors, and handling errors in Promises and Async/Await. Proper error handling is essential for building robust applications that can handle unexpected situations gracefully.

In the next lesson, we will explore The DOM (Document Object Model), where you will learn how to interact with and manipulate HTML and CSS in your web applications.