JS Error Handling

Error Handling

Introduction: What is an Error in JavaScript?

In programming, errors are problems that happen when your code is running. It’s like when you’re playing a game and something unexpected happens like your character getting stuck in a wall. In coding, if something unexpected happens, it’s called an error.

Why Should We Care About Errors?

When an error happens, it can stop the program from working. It’s important to catch and handle these errors so the program can keep running smoothly or show a helpful message to the user. Think of it like fixing a flat tire while driving, so you can continue your journey without getting stuck.

How to Handle Errors in JavaScript?

Now, let’s talk about how we can deal with errors in a smart way using try, catch, and finally. These tools let us handle errors without our program crashing.

JS-handle-errors

In JavaScript, there are tools to handle errors and keep your program from crashing completely.

1. Try...Catch: Catching and Fixing Errors

You can tell JavaScript to “try” doing something. If it makes a mistake, you can “catch” the error and fix it or show a message to the user.

Here’s how it works:

•  try block: You put the code that might have an error inside a try block.

  catch block: If there’s an error in the try block, the code in the catch block runs, and you can handle the error.

Example:

try {
let number = 10;
console.log(number.toUpperCase()); // Error, because ‘number’ is not a string
} catch (error) {
console.log(“Oops! Something went wrong: ” + error.message);
}

Code Explanation:

1. The try Block:

try {
let number = 10;
console.log(number.toUpperCase()); // Error, because ‘number’ is not a string
}

The try block is where we place the code that we want to execute, but it might cause an error.
In this case, we have:
•   let number = 10;: This creates a variable called number and sets it to the value 10 (a number).
•   console.log(number.toUpperCase());: This line tries to call .toUpperCase() on the number. The method .toUpperCase() is only available for strings in            JavaScript (it converts all letters of a string to uppercase), but number is a number, not a string.

Since number is not a string, JavaScript will throw an error. The error will stop the execution of the code in the try block and jump to the catch block to handle the error.

2. The catch Block:a

catch (error) {
console.log(“Oops! Something went wrong: ” + error.message);
}

The catch block is used to handle any errors that occur in the try block.

If an error occurs inside the try block, JavaScript jumps to the catch block and executes the code there.

The catch block has an error parameter that holds the error object thrown by the program. This object contains useful information about the error, such as:
•   The message (a description of the error).
•   The name of the error (e.g., TypeError, ReferenceError).
   Stack trace details (optional, for debugging).

In this case, the error is caused by trying to call .toUpperCase() on a number, which is not valid.

•   console.log(“Oops! Something went wrong: ” + error.message);: This line prints a message to the console. The error.message part gets the message            from the error object, which will explain what went wrong.

Since the error is a TypeError (because .toUpperCase() is not a method for numbers), the output will be:

JS-The-catch-block
Output:
JS-Catch-output

2. Throwing Errors: Creating Your Own Errors

Sometimes you want to create an error yourself. You can throw an error when something goes wrong.

Here’s how:

function checkAge(age) {
if (age < 18) {
throw new Error(“Sorry, you must be 18 or older to enter.”);
} else {
console.log(“Welcome!”);
}
}

try {
checkAge(15); // Throws an error
} catch (error) {
console.log(error.message); // Outputs: Sorry, you must be 18 or older to enter.
}

Code Explanation:

Function Definition: checkAge

function checkAge(age) {
if (age < 18) {
throw new Error(“Sorry, you must be 18 or older to enter.”);
} else {
console.log(“Welcome!”);
}
}

The function checkAge takes one parameter: age, which represents the age of a person.

Inside the function, there’s an if statement that checks if the age is less than 18:

If the age is less than 18, it triggers an error using the throw keyword:

throw new Error(“Sorry, you must be 18 or older to enter.”);

This throw statement creates a new Error object with a custom message (“Sorry, you must be 18 or older to enter.”) and throws the error, which stops the function from continuing. When an error is thrown, it must be caught by a try-catch block to handle the error.

If the age is 18 or older, it will print “Welcome!” to the console.

Error Handling with try-catch

try {
checkAge(15); // Throws an error
} catch (error) {
console.log(error.message); // Outputs: Sorry, you must be 18 or older to enter.
}

The try-catch block is used to handle errors that might occur within the try block.

try Block: This contains the code that might throw an error. In this case, the function checkAge(15) is called with 15 as the argument. Since 15 is less than 18, the checkAge function will throw an error, and the flow will immediately jump to the catch block.

catch Block: If an error is thrown in the try block, the catch block will execute. The catch block receives the thrown error as a parameter (called error here).

The error.message property contains the message from the Error object that was thrown in the checkAge function.

In this case, it logs the message: “Sorry, you must be 18 or older to enter.”

Output:
JS-Throwing-errors

3. Finally Block: Code That Always Runs

Sometimes, you want to make sure that something runs no matter what happens, whether there’s an error or not. This is where the finally block comes in.

try {
let num = 10;
console.log(num.toUpperCase()); // Error!
} catch (error) {
console.log(“An error occurred: ” + error.message);
} finally {
console.log(“This will always run, no matter what.”);
}

Code Explanation:

1. try Block

try {
let num = 10;
console.log(num.toUpperCase()); // Error!
}

console.log(num.toUpperCase());: This line attempts to call the toUpperCase() method on the variable num, which is a number (10).

Why does this cause an error?

The method toUpperCase() is a string method, not a method for numbers. Since num is a number, JavaScript will throw a TypeError because you cannot call toUpperCase() on a number.

So, an error is thrown, and the rest of the code in the try block is skipped. The flow moves to the catch block.

2. catch Block

catch (error) {
console.log(“An error occurred: ” + error.message);
}

The catch block is used to catch and handle the error thrown by the try block.

The error object represents the thrown error and error.message contains the error message string.

In this case, the error message will be “num.toUpperCase is not a function” because calling toUpperCase() on a number is not valid.

The catch block will print:

An error occurred: num.toUpperCase is not a function

3. finally Block

finally {
console.log(“This will always run, no matter what.”);
}

The finally block is always executed, regardless of whether an error was thrown or not.

Even if no error occurs, the finally block will run.

In this case, since an error is thrown in the try block, the finally block still runs after the catch block finishes.

It will print:

This will always run, no matter what.

Output:

Types of Errors in JavaScript

JavaScript has different kinds of errors. Let’s look at the main types:

The Error Object

JavaScript has a built-in error object that provides error information when an error occurs.

The error object provides two useful properties: name and message.

Error Object Properties

PROPERTY DESCRIPTION
NAME Sets or returns an error name
MESSAGE Sets or returns an error message (a string)

Range Error

A RangeError is thrown if you use a number that is outside the range of legal values.

For example: You cannot set the number of significant digits of a number to 500.

Codepen
<!DOCTYPE html>
<html>
<body>
<h1>JavaScript Errors</h1>
<h2>The RangeError</h2>
<p>You cannot set the number of significant digits too high:</p>
<p id=”demo”>
<script>
let num = 1;
try {
num.toPrecision(500);
}
catch(err) {
document.getElementById(“demo”).innerHTML = err.name;
}
</script>
</body>

Reference Error

A ReferenceError is thrown if you use (reference) a variable that has not been declared:

<!DOCTYPE html>
<html>
<body>
<h1>JavaScript Errors</h1>
<h2>The ReferenceError</h2>
<p>You cannot use the value of a non-existing variable:</p>
<p id=”demo”></p>
<script>
let x = 5;
try {
x = y + 1;
}
catch(err) {
document.getElementById(“demo”).innerHTML = err.name;
}
</script>
</body>
</html>

Syntax Error

A SyntaxError is thrown if you try to evaluate code with a syntax error.

<!DOCTYPE html>
<html>
<body>
<h1>JavaScript Errors</h1>
<h2>The SyntaxError</h2>
<p>You cannot evaluate code that contains a syntax error:</p>
<p id=”demo”></p>
<script>
try {
eval(“alert(‘Hello)”);
}
catch(err) {
document.getElementById(“demo”).innerHTML = err.name;
}
</script>
</body>
</html>

Type Error

A TypeError is thrown if an operand or argument is incompatible with the type expected by an operator or function.

<!DOCTYPE html>
<html>
<body>
<h1>JavaScript Errors</h1>
<h2>The TypeError</h2>
<p>You cannot convert a number to upper case:</p>
<p id=”demo”></p>
<script>
let num = 1;
try {
num.toUpperCase();
}
catch(err) {
document.getElementById(“demo”).innerHTML = err.name;
}
</script>
</body>
</html>

URI (Uniform Resource Identifier) Error

A URIError is thrown if you use illegal characters in a URI function:

<!DOCTYPE html>
<html>
<body>
<h1>JavaScript Errors</h1>
<h2>The URIError</h2>
<p>Some characters cannot be decoded with decodeURI():</p>
<p id=”demo”></p>
<script>
try {
decodeURI(“%%%”);
}
catch(err) {
document.getElementById(“demo”).innerHTML = err.name;
}
</script>
</body>
</html>

Course Video

Course Video

1. Print the Error using Error Handling and also Print ” I am Finally “Whether the code shows Error Or Not.

The task is to use error handling in JavaScript to catch and print an error, and then print a message regardless of whether an error occurred or not.
1. Try Block:
Use a try block to wrap the code that might throw an error.
2. Catch Block:
Use a catch block to catch and handle the error. Inside the catch block, log the error.
3. Finally Block:
Use a finally block to include code that will be executed regardless of whether an error occurred or not. Log the message “I am Finally” inside the finally block.

Here’s an example program:

try {
// Code that might throw an error
// For example, trying to access an undefined variable
console.log(undefinedVariable); // This will throw a ReferenceError
} catch (error) {
// Catch block to handle the error
console.error(“Error:”, error.message);
} finally {
// Finally block to execute code regardless of an error
console.log(“I am Finally”);
}

Output
2. Write a function that takes two parameters (a and b) and calculates the division of a by b. Implement error handling to check if b is zero and throw a custom error in such a case. Catch the error and log an appropriate message. Test the function with different values of a and b, including scenarios where b is zero.

The task is to write a JavaScript function that performs division of two parameters (a and b). The function should include error handling to check if b is zero, and if so, it should throw a custom error. You need to catch this error and log an appropriate message. Finally, test the function with different values of a and b, including scenarios where b is zero.
1. Write a Function:
Define a function that takes two parameters a and b.
2. Error Handling:
– Use error handling to check if b is zero.
– If b is zero, throw a custom error using the throw statement.
3. Catch Block:
Use a catch block to catch the custom error and log an appropriate message.
4. Test the Function:
Test the function with different values of a and b, including scenarios where b is zero.

Here’s an example program:

function divide(a, b) {
try {
// Check if b is zero
if (b === 0) {
// Throw a custom error if b is zero
throw new Error(“Division by zero is not allowed”);
}

Output
3.Handling Asynchronous Errors with try...catch:
Objective:

Handle errors in asynchronous code (e.g., inside a Promise) using async/await and try…catch.

Steps:

  Define an asynchronous function fetchData() that simulates fetching data.
•   Use try…catch to handle any errors that may occur during the async operation

Here’s an example program:

async function fetchData(url) {
try {
if (!url) {
throw new Error(“URL is required”);
}
return `Fetched data from ${url}`;
} catch (error) {
return error.message;
}
}
fetchData(“https://api.example.com”)
.then(result => console.log(result)); // Output: Fetched data from https://api.example.com
fetchData(“”)
.then(result => console.log(result)); // Output: URL is required

Output
4. Nested try...catch Blocks:
Objective:

Demonstrate the use of nested try…catch blocks to handle errors in complex functions.

Steps:

   Define a function processNestedData(data) that processes nested data.
   Inside this function, use a try…catch block to handle errors from the data processing.
•   Inside the catch, add another try…catch block to handle different errors.

Here’s an example program:

function processNestedData(data) {
try {
if (!data.main) {
throw new Error(“Main data is missing”);
}
try {
if (!data.main.sub) {
throw new Error(“Sub data is missing”);
}
return `Processed sub data: ${data.main.sub}`;
} catch (error) {
return `Error in sub data: ${error.message}`;
}
} catch (error) {
return `Error in main data: ${error.message}`;
}
}
console.log(processNestedData({ main: { sub: “valid” } })); // Output: Processed sub data: valid
console.log(processNestedData({ main: {} })); // Output: Error in sub data: Sub data is missing
console.log(processNestedData({})); // Output: Error in main data: Main data is missing

Output
5. Using finally for Cleanup Code:
Objective:

Demonstrate the usage of finally to ensure some cleanup code is always executed after try…catch.

Steps:

   Define a function processData(data) that simulates processing data.
•   Use try…catch to handle errors and finally to log a cleanup message.

Here’s an example program:

function processData(data) {
try {
if (data === null) {
throw new Error(“Data is required”);
}
return `Processing data: ${data}`;
} catch (error) {
return error.message;
} finally {
console.log(“Cleanup done.”);
}
}

console.log(processData(“Valid data”)); // Output: Processing data: Valid data \n Cleanup done.
console.log(processData(null)); // Output: Data is required \n Cleanup done.

Output
Frequently Asked Questions

Still have a question?

Let's talk

Error handling refers to the techniques used to manage and respond to runtime errors in JavaScript, ensuring that the program continues running smoothly. Learn more in our JavaScript error handling free course video.

A try…catch block handles exceptions. Code that might throw an error is placed in the try block, while errors are caught in the catch block.
Example:

try { 

  let x = y; // ReferenceError: y is not defined 

} catch (error) { 

  console.log(error.message); 

Explore this concept in the JS error handling with free video tutorial.

The finally block executes code after try and catch regardless of whether an error occurred. It is useful for cleanup tasks.
Example:

Use the throw statement to create custom errors.
Example:

throw new Error(“Custom error message”); 

Watch practical examples in the JavaScript error handling with free tutorial.

Common error types include:

  • SyntaxError: Issues with syntax.
  • ReferenceError: Using an undeclared variable.
  • TypeError: Mismatched data types.
  • RangeError: Number out of range.
    Learn about these error types in the JavaScript error handling free course video.

Yes, but only within async functions. For Promises, use .catch() for error handling.
Example with async/await:

async function fetchData() { 

  try { 

    let response = await fetch(“invalid-url”); 

  } catch (error) { 

    console.log(error.message); 

  } 

Discover more in the JS error handling with free video tutorial.

Use console.error() to log error messages for debugging. Tools like Sentry and LogRocket can also be used for advanced error monitoring. Explore this in the Free JavaScript error handling tutorial for beginners.

The Error object represents runtime errors. It includes properties like message and name to describe the error. Check this out in the JavaScript error handling with free tutorial.

  • Always use try…catch for risky code.
  • Use meaningful error messages for debugging.
  • Avoid catching errors you can’t handle.
  • Log errors for monitoring.
    Find best practices in the JavaScript error handling free course video.

Extend the built-in Error class to create custom error types.
Example:

class CustomError extends Error { 

  constructor(message) { 

    super(message); 

    this.name = “CustomError”; 

  } 

Explore this topic in the JS error handling with free video tutorial.