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.

Take your presentation to the next level.

Put your face and name on your screen.

Your to-dos on your menu bar.

Fill forms using your right-click menu.

Ram Patra Published on August 1, 2024
Image placeholder

Keep reading

If this article was helpful, others might be too

question typescript javascript August 11, 2024 What is module inside compilerOptions in tsconfig.json and what to use?

The module option inside compilerOptions in the tsconfig.json file of a TypeScript project specifies the module code generation system that the TypeScript compiler should use when emitting JavaScript. This option determines how the TypeScript code will be transformed into JavaScript modules, affecting how modules are loaded, interpreted, and linked in the resulting JavaScript code.

question typescript react September 28, 2024 How to add a custom element to a Next.js/Typescript project?

Let’s say I have a custom element setapp-badge that I want to use in my tsx files. If I go ahead and use it, the compiler will throw an error and Next.js will fail to build. It seems the problem might be a combination of how Next.js, TypeScript, and custom elements work together. Therefore, let’s try an approach that avoids the namespace/module issues while ensuring custom elements are recognized in a Next.js/TypeScript project.

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.

Like my work?

Please, feel free to reach out. I would be more than happy to chat.