Handling Errors in Node.js: Turning Oops into Success 🚀

Khushi Patel - Sep 1 - - Dev Community

Errors are like uninvited guests, Let me share with you how I’ve learned to handle errors in Node.js, transforming those "Oops" moments into success.
The key point here is "Expect the Unexpected"

Expect

Understanding Errors: The Usual Suspects

Before we dive into handling errors, Let me recall you types of ERROR In Node.js, errors typically fall into a few categories:

Syntax Errors: (They usually happen when you forget a } or add an extra). Node.js will shout at you (in red text) and refuse to run your code until you fix it (Thanks to compiler! 🙏🏻).

Runtime Errors: These occur when your code tries to do something impossible(reading a property of undefined).

Logical Errors: These are the sneaky ones. Your code runs without crashing, but it doesn’t do what it’s supposed to.

Operational Errors: They’re often caused by factors outside of your control, but they’re still your responsibility to handle (when your database suddenly decided to take nap!!😂).

Error Handling: My Go-To Techniques

1. Try-Catch: The First Line of Defence
When working with asynchronous code, try-catch is your best friend. I’ve found that wrapping code in a try-catch block can save you a lot of headaches.

async function fetchData() {
    try {
        const data = await someAsyncFunction();
        return data;
    } catch (error) {
        console.error('Error fetching data:', error.message);
        throw new Error('Failed to fetch data');
    }
}
Enter fullscreen mode Exit fullscreen mode

2. Centralized Error Handling: Keeping Things Organized
I centralize my error handling in one place—usually a middleware function. This approach keeps my code clean and makes it easier to manage errors across the entire application.

app.use((err, req, res, next) => {
    console.error(err.stack);
    res.status(500).json({ message: 'Something went wrong!' });
});
Enter fullscreen mode Exit fullscreen mode

3. Custom Error Classes: Making Errors Work for You
I create custom error classes. This allows me to throw meaningful errors that can be handled differently depending on the situation.

class NotFoundError extends Error {
    constructor(message) {
        super(message);
        this.name = 'NotFoundError';
        this.statusCode = 404;
    }
}

throw new NotFoundError('Resource not found');
Enter fullscreen mode Exit fullscreen mode

4. Promise Rejection Handling: Because Promises Don’t Always Keep Theirs
Working with Promises? Then you’ve probably run into the dreaded unhandled promise rejection. It’s important to catch these errors too, as they can easily slip by unnoticed if you’re not careful.

process.on('unhandledRejection', (reason, promise) => {
    console.error('Unhandled Rejection at:', promise, 'reason:', reason);
    // Application-specific logging, throwing an error, or other logic here
});
Enter fullscreen mode Exit fullscreen mode

Conclusion: Turning Oops into Success

By handling errors thoughtfully and proactively, you not only improve your code but also create a better experience for your users.

Happy coding ! 🫶🏻

. . . . . . . . . . . . . . . .