How to Handle Errors in Node.js

#node.js

#handle errors

Handling errors in Node.js is crucial for creating robust and reliable applications. Here’s a comprehensive guide on how to handle errors effectively in Node.js.

1. Types of Errors

Errors in Node.js can be broadly categorized into three types:

  • Synchronous Errors: These occur during the execution of synchronous code.
  • Asynchronous Errors: These occur in asynchronous operations, such as callbacks, promises, and async/await.
  • Operational Errors: These are anticipated errors such as network issues, invalid user input, etc.
  • Programmer Errors: Bugs in the code, such as undefined variables, type errors, etc.

2. Basic Error Handling


Try-Catch Block

Use try-catch blocks to handle synchronous errors.

try {
  // Code that may throw an error
  let result = someFunction();
} catch (error) {
  // Handle the error
  console.error('Error occurred:', error.message);
}

Callback Error Handling

Pass errors to the callback function to handle errors in asynchronous code.

function someAsyncFunction(callback) {
  fs.readFile('/file-does-not-exist', (err, data) => {
    if (err) {
      return callback(err);
    }
    callback(null, data);
  });
}

someAsyncFunction((err, data) => {
  if (err) {
    console.error('Error occurred:', err.message);
  } else {
    console.log(data);
  }
});

3. Handling Promises


Using `.catch()`

Handle errors in promises with `.catch()`.

somePromiseFunction()
  .then(result => {
    // Handle result
  })
  .catch(error => {
    // Handle error
    console.error('Error occurred:', error.message);
  });

Using `try-catch` with `async/await`

Handle errors in async functions using `try-catch`.

async function someAsyncFunction() {
  try {
    let result = await somePromiseFunction();
    // Handle result
  } catch (error) {
    // Handle error
    console.error('Error occurred:', error.message);
  }
}

someAsyncFunction();

4. Global Error Handling


Uncaught Exceptions

Handle uncaught exceptions globally.

process.on('uncaughtException', (error) => {
  console.error('Uncaught Exception:', error.message);
  // Consider shutting down the process safely
});

Unhandled Promise Rejections

Handle unhandled promise rejections globally.

process.on('unhandledRejection', (reason, promise) => {
  console.error('Unhandled Rejection at:', promise, 'reason:', reason);
  // Consider shutting down the process safely
});

5. Creating Custom Error Classes

Create custom error classes for more specific error handling.

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

try {
  throw new CustomError('This is a custom error');
} catch (error) {
  console.error(error.name); // CustomError
  console.error(error.message); // This is a custom error
}

6. Error Handling Middleware in Express.js

In an Express.js application, use error-handling middleware to handle errors.

const express = require('express');
const app = express();

// Middleware to handle errors
app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(500).send('Something broke!');
});

// Example route that triggers an error
app.get('/', (req, res) => {
  throw new Error('BROKEN'); // Express will catch this on its own
});

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

7. Best Practices

  • Graceful Shutdown: Ensure the application can shut down gracefully when an error occurs.
  • Logging: Use proper logging mechanisms (e.g., Winston, Bunyan) to log errors.
  • Validation: Validate inputs to prevent errors.
  • Monitoring: Use monitoring tools (e.g., New Relic, Sentry) to keep track of errors in production.

By following these practices and utilizing the different error-handling mechanisms provided by Node.js, you can create resilient applications that can handle errors gracefully and maintain stability.

Further, if you have any questions, please visit our websiteGurulabs Website Design Agency.