Loading...

How to bubble up errors or exceptions from one method to another in Typescript?

question typescript
Ram Patra Published on August 1, 2024

In TypeScript, you can “bubble up” errors or exceptions from one method to another by allowing exceptions to propagate through the call stack. Here’s how you can achieve this with examples:

1. Basic Propagation of Errors

In TypeScript, you can throw errors from one method and catch them in a higher-level method, or let them propagate up to the top-level caller if they are not caught. Here’s a simple example demonstrating this:

class Example {
    method1() {
        try {
            this.method2();
        } catch (error) {
            console.error('Error caught in method1:', error);
            // You can choose to handle the error here or rethrow it
        }
    }

    method2() {
        // This will throw an error
        throw new Error('Something went wrong in method2');
    }
}

const example = new Example();
example.method1();

In this example, method2 throws an error that method1 catches. You can choose to handle the error in method1 or let it propagate further if method1 does not catch it.

2. Rethrowing Errors

If you catch an error in one method but want to let it bubble up to a higher level, you can rethrow it using throw:

class Example {
    method1() {
        try {
            this.method2();
        } catch (error) {
            console.error('Error caught in method1, rethrowing...');
            throw error; // Rethrow the error to let it propagate
        }
    }

    method2() {
        // This will throw an error
        throw new Error('Something went wrong in method2');
    }
}

const example = new Example();
try {
    example.method1();
} catch (error) {
    console.error('Error caught in the outer scope:', error);
}

In this example, the error thrown in method2 is caught and rethrown by method1, and then caught in the outer try...catch block where method1 is called.

3. Custom Error Types

You can define custom error types for more specific error handling. Here’s how you can use custom errors to provide more context:

class CustomError extends Error {
    constructor(message: string) {
        super(message);
        this.name = 'CustomError';
    }
}

class Example {
    method1() {
        try {
            this.method2();
        } catch (error) {
            if (error instanceof CustomError) {
                console.error('CustomError caught in method1:', error);
            } else {
                console.error('General error caught in method1:', error);
            }
            throw error; // Rethrow the error to let it propagate
        }
    }

    method2() {
        // This will throw a CustomError
        throw new CustomError('Something went wrong in method2');
    }
}

const example = new Example();
try {
    example.method1();
} catch (error) {
    console.error('Error caught in the outer scope:', error);
}

4. Async Methods

For asynchronous methods, you should use async/await syntax, and you can propagate errors in a similar fashion:

class Example {
    async method1() {
        try {
            await this.method2();
        } catch (error) {
            console.error('Error caught in method1:', error);
            throw error; // Rethrow the error to let it propagate
        }
    }

    async method2() {
        // This will throw an error
        throw new Error('Something went wrong in method2');
    }
}

const example = new Example();
example.method1().catch(error => {
    console.error('Error caught in the outer scope:', error);
});

In this asynchronous example, method2 throws an error that method1 catches, handles, and rethrows. The catch block outside of method1 handles any errors that bubble up.

Summary

  • Throw errors: Use throw to throw exceptions from methods.
  • Catch and rethrow: Use try...catch to handle exceptions in one method and optionally rethrow them.
  • Custom errors: Define and use custom error types for more specific error handling.
  • Async errors: Use async/await for handling errors in asynchronous methods.

This approach ensures that errors can be properly managed and handled at different levels of your application.

Ram Patra Published on August 1, 2024
Image placeholder

Keep reading

If this article was helpful, others might be too

question typescript javascript July 17, 2024 Difference between ?? and || in Typescript or Javascript?

In TypeScript (and JavaScript), the ?? (nullish coalescing operator) and || (logical OR operator) are both used to provide default values, but they behave differently in terms of the conditions under which they return the right-hand operand.

question typescript July 28, 2024 How to pass a generic JSON object as a parameter to a method in TypeScript?

If you want to allow any JSON object without specifying its structure, you can use the object type, Record<string, any>, or simply any. However, each approach has its own implications for type safety and flexibility.

question typescript July 20, 2024 How to filter an Array based on a condition in Typescript?

Filtering an array based on a condition in TypeScript is straightforward and similar to how you would do it in JavaScript. TypeScript adds type safety to the process, ensuring that your code is more robust and less error-prone.