HOLIDAY SALE! Save 50% on Membership with code HOLIDAY50. Save 15% on Mentorship with code HOLIDAY15.

8) Connecting to the Wider Web Lesson

JavaScript Error Catching and Throwing

12 min to complete · By Ian Currie

Sometimes, especially when your script depends on an external source, such as requests, you can't be sure it will run without errors. Maybe the server is down. Maybe your internet has gone down. It is a good idea to catch or anticipate errors that your code might produce. This way, you can handle them in a way that is appropriate for your script.

Why do you Need the Javascript try...catch Block?

If you call a function that doesn't exist and then console.log() something, what will happen? Try the below to find out:

iDontExist();
console.log("script finished (ᵔᴥᵔ)");

The interpreter will, understandably, throw an error and then stop the script. That may not be ideal: sometimes you'll want to try and do something if possible, and then continue the script.

How to Use the Try Catch Block

Have a look at this example using the try ... catch block:

try {
  iDontExist();
} catch (error) {}

console.log("script finished (ᵔᴥᵔ)");

Calling iDontExist() produces an error, but you have a catch block to capture that error so the script carries on. It's as if you never called iDontExist() at all. This is because there is nothing in the catch block.

The fact that it doesn't log anything to the console may not be ideal, though. You will usually want to know if your code ran into any errors, which you can do like this:

const tao = "unchanging";

try {
  tao = "I change you";
} catch (error) {
  console.error("ಠ_ಠ");
}

console.log("script finished (ᵔᴥᵔ)");

The code above caught the error, logged an angry face to the console, and then carried on to print the completion message. It did this by including instructions within the curly braces of the catch block.

You will see how in these examples the "argument" passed to the catch "function" is error. This can be named anything you like, but the convention is to pass error, err, or e, because whatever name you use here serves as an identifier for the catch block to assign the error object to.

This is because when JavaScript throws an error, it creates an error object. The error object then travels up the call stack until it is caught by a catch block. If there is no catch block, the script will stop running.

The error object has methods of its own, and can also be console logged:

try {
  iDontExist();
} catch (e) {
  console.log(e); // ReferenceError: iDontExist is not defined
}
console.log("script finished (ᵔᴥᵔ)");

The error object also has a property called message:

try {
  iDontExist();
} catch (e) {
  console.error(e.message); // iDontExist is not defined
}
console.log("script finished (ᵔᴥᵔ)");

The try ... catch block is a great way to anticipate errors and handle them.

However, there may come a time when JavaScript doesn't consider something an error, and yet for your purposes, it should be considered an error. To make sure an error is thrown, you can use the throw statement.

## How to Use the throw Statement

To throw an error, you can use the throw statement. This will throw an error, and stop the script:

throw "I am an error"; // Uncaught I am an error

You can also throw an error object:

throw new Error("I am an error object"); // Uncaught Error: I am an error object

You can also throw a specific type of error:

throw new ReferenceError("I am a reference error"); // Uncaught ReferenceError: I am a reference error

Throwing errors should be used when you encounter exceptional situations that should be considered an error. They should not be used for normal flow control.

How to Use the try...catch...finally Block

There is a third part to the try catch block, and it is called finally. This is a block that will run whether or not there is an error. It is a good place to put code that you want to run no matter what.

try {
  iDontExist();
} catch (e) {
  console.log(e.message);
} finally {
  console.log("try catch block finished");
}

console.log("script finished (ᵔᴥᵔ)");

How to Handle Specific Errors With the Javascript instanceof Keyword

There are many different types of error, and sometimes you might want to do something specific if the error is of a specific type.

Here is a list of all the errors in JavaScript.

Here is how you might adapt a try catch block to identify which type of error it is, using the instanceof keyword:

try {
  myroutine(); // may throw three types of exceptions
} catch (e) {
  if (e instanceof TypeError) {
    // statements to handle TypeError exceptions
  } else if (e instanceof RangeError) {
    // statements to handle RangeError exceptions
  } else if (e instanceof ReferenceError) {
    // statements to handle ReferenceError exceptions
  } else {
    // statements to handle any unspecified exceptions
    throw e; // rethrowing the exception
  }
}

In this example you can see that the instanceof keyword is used to check if the error is of a specific type. If it is, then you can handle it in a specific way. If it isn't, then you can throw it again.

It can be good practice to catch specific errors and handle them in a specific way, and then throw any other errors again. While developing, this approach can help you identify and address unanticipated problems in your code more effectively. By rethrowing errors that you haven't explicitly handled, you avoid masking issues that might require attention.

This method ensures that unexpected errors don't silently fail, enabling you to catch them during development or testing phases. It promotes a more proactive debugging process, where you become aware of and can fix issues as they arise, rather than allowing them to go unnoticed.

This approach also helps maintain clear code accountability, as it delineates between known, handled exceptions and other issues that might indicate a gap in your error-handling logic or a flaw in the program's design.

Summary: How to Handle Errors With the Javascript Try...Catch Block

You've gained valuable insights into error handling in JavaScript, equipping you with tools to make your code more robust. You've:

  • Discovered the try...catch block, an error handling mechanism that continues script execution even when you encounter errors.
  • Understood that errors in JavaScript create an error object.
  • Learned that using the throw statement allows you to create custom errors which is useful when JavaScript doesn't flag something as an error, but it should be for your script's purposes.
  • Explored the use of try...catch...finally block, where finally runs code regardless of whether an error occurred, ensuring some operations are always performed.
  • Found out how to handle specific errors using the instanceof keyword, allowing for granular control over different error types which can improve debugging and code clarity.

Always remember, effective error handling is critical for creating resilient and user-friendly applications!