Skip to main content

Command Palette

Search for a command to run...

Error Handling in JavaScript: Try, Catch, Finally

Updated
7 min readView as Markdown

JavaScript applications rarely run perfectly all the time. A user may enter invalid input, an API request may fail, or a function may try to access something that does not exist. These situations create errors.

If errors are not handled properly, applications can crash, behave unpredictably, or become difficult to debug.

This is where JavaScript error handling becomes important.

In this blog, you will learn:

  • What errors are in JavaScript

  • How try and catch blocks work

  • The purpose of the finally block

  • How to throw custom errors

  • Why proper error handling matters


What Are Errors in JavaScript?

An error is a problem that interrupts the normal execution of a program.

For example:

console.log(user.name);

If user is not defined, JavaScript throws an error like this:

ReferenceError: user is not defined

The program stops executing at that point unless the error is handled properly.


Common Types of JavaScript Errors

Here are some common runtime errors developers encounter:

Error Type Meaning
ReferenceError Variable does not exist
TypeError Invalid operation on a value
SyntaxError Invalid JavaScript syntax
RangeError Value out of allowed range
Error Generic error object

Example of a TypeError:

const num = 10;

num.toUpperCase();

Output:

TypeError: num.toUpperCase is not a function

Numbers do not have the toUpperCase() method, so JavaScript throws an error.


Why Error Handling Matters

Without proper error handling:

  • Applications may crash

  • Users may see blank screens

  • Bugs become harder to identify

  • Important operations may fail silently

Good error handling helps developers:

  • Detect problems quickly

  • Prevent application crashes

  • Show meaningful messages to users

  • Debug issues efficiently

  • Build stable applications

Instead of letting the program fail abruptly, error handling allows applications to fail gracefully.


The Problem Without Error Handling

Consider this code:

console.log("Program started");

const user = JSON.parse("invalid json");

console.log("Program ended");

Output:

Program started
SyntaxError: Unexpected token i in JSON

The last line never runs because the error stops execution.

This can become dangerous in larger applications.


Using try and catch Blocks

JavaScript provides try and catch blocks to handle errors safely.

Basic syntax:

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

How try Works

The try block contains code that might fail.

Example:

try {
    const result = JSON.parse("invalid json");
    console.log(result);
}

If an error occurs, JavaScript immediately stops executing the try block and moves to catch.


How catch Works

The catch block receives the error object.

Example:

try {
    const result = JSON.parse("invalid json");
} catch (error) {
    console.log("Something went wrong");
    console.log(error.message);
}

Output:

Something went wrong
Unexpected token i in JSON

Instead of crashing the application, the error is handled gracefully.


Understanding the Error Object

The catch block receives an error object containing useful debugging information.

Example:

try {
    let data = JSON.parse("wrong");
} catch (error) {
    console.log(error.name);
    console.log(error.message);
}

Output:

SyntaxError
Unexpected token w in JSON

Useful properties:

Property Description
error.name Type of error
error.message Error message
error.stack Stack trace for debugging

Real-World Example of try and catch

Suppose a user enters JSON data into a form.

const userInput = '{"name":"Aslam"}';

try {
    const user = JSON.parse(userInput);
    console.log(user.name);
} catch (error) {
    console.log("Invalid JSON format");
}

If the input is valid, the program works normally.

If the input is invalid, the application handles the error instead of crashing.

This creates a better user experience.


The finally Block

The finally block runs no matter what happens.

It executes:

  • Whether an error occurs or not

  • Whether the try block succeeds or fails

Syntax:

try {
    // risky code
} catch (error) {
    // handle error
} finally {
    // always runs
}

Example of finally

try {
    console.log("Connecting to database");
} catch (error) {
    console.log("Connection failed");
} finally {
    console.log("Closing connection");
}

Output:

Connecting to database
Closing connection

The finally block is useful for cleanup tasks.


Common Uses of finally

Developers commonly use finally for:

  • Closing database connections

  • Stopping loaders/spinners

  • Releasing resources

  • Cleaning temporary files

  • Logging completion status

Example:

try {
    console.log("File opened");
} catch (error) {
    console.log("Error occurred");
} finally {
    console.log("File closed");
}

Even if an error occurs, the file still gets closed properly.


Throwing Custom Errors

JavaScript also allows developers to create their own errors using throw.

Syntax:

throw new Error("Message");

Why Throw Custom Errors?

Custom errors help when:

  • Validating user input

  • Enforcing business rules

  • Detecting invalid states

  • Creating meaningful debugging messages


Example of throw

const age = 15;

try {
    if (age < 18) {
        throw new Error("User must be at least 18 years old");
    }

    console.log("Access granted");
} catch (error) {
    console.log(error.message);
}

Output:

User must be at least 18 years old

This gives developers full control over error handling.


Throwing Different Types of Errors

You can throw different error types as well.

Example:

throw new TypeError("Invalid data type");

Or:

throw new RangeError("Value out of range");

Using specific error types improves debugging and code clarity.


Graceful Failure in Applications

Good applications do not completely break when something fails.

Instead, they:

  • Show error messages

  • Retry operations

  • Log issues for developers

  • Continue functioning where possible

For example:

try {
    const response = fetchData();
    displayData(response);
} catch (error) {
    showErrorMessage("Unable to load data");
}

This approach protects the user experience.


Nested try and catch Blocks

JavaScript also allows nested error handling.

Example:

try {
    try {
        JSON.parse("wrong");
    } catch (error) {
        console.log("Inner error handled");
    }
} catch (error) {
    console.log("Outer error handled");
}

Nested handling is useful in large applications but should be used carefully to avoid complexity.


Best Practices for Error Handling

1. Handle Errors Properly

Do not ignore errors silently.

Bad:

catch (error) {

}

Good:

catch (error) {
    console.log(error.message);
}

2. Use Meaningful Error Messages

Clear messages make debugging easier.

Bad:

throw new Error("Wrong");

Good:

throw new Error("Email format is invalid");

3. Avoid Excessive try Blocks

Only wrap code that may fail.

Bad:

try {
    // huge application logic
}

Good:

try {
    JSON.parse(data);
}

4. Log Errors During Development

Logging helps developers identify problems quickly.

Example:

catch (error) {
    console.error(error);
}

5. Do Not Expose Sensitive Errors to Users

Developers need detailed errors.

Users need simple messages.

Bad:

DatabaseError: Connection failed at port 3306

Better:

Something went wrong. Please try again later.

Error Handling in Asynchronous JavaScript

Errors also happen in asynchronous code.

Example using async/await:

async function getData() {
    try {
        const response = await fetch("https://api.example.com/data");

        const data = await response.json();

        console.log(data);
    } catch (error) {
        console.log("Failed to fetch data");
    }
}

This is extremely common in modern JavaScript applications.


Final Thoughts

Errors are a normal part of software development. What separates strong applications from unstable ones is how those errors are handled.

JavaScript provides powerful tools like:

  • try

  • catch

  • finally

  • throw

These features help developers:

  • Prevent crashes

  • Handle failures gracefully

  • Improve debugging

  • Build reliable applications

1 views