DEV Community

chethancm2001
chethancm2001

Posted on

A Structured Approach For Error Handling In Express.js

One of the most crucial parts of any application is error handling. If errors are not handled properly, the application may crash, significantly reducing its availability.
 alt text
In the context of Express, it has a built-in middleware that automatically directs errors from controllers to the error-handling middleware. Whenever an error occurs in any controller, it is automatically passed to the error-handling middleware. The error-handling middleware is a regular middleware that accepts four parameters: error along with req, res, and next. If multiple error-handling middlewares are present, the error is passed to the next middleware in line.

app.get("/error",(req,res)=>{
// creating the error
new Error("raisig the errror")
}

//Error handling middleware
app.use((err,req,res,next)=>{
res.status(500).json({message:"something went worng")
})
Enter fullscreen mode Exit fullscreen mode

In our quest to master error handling in Express.js, we've gone beyond the basics, crafting a collection of custom errors tailored for specific scenarios. Whether it's handling unauthorized access, gracefully dealing with no data found, validating data schemas, managing rate limits, or addressing forbidden access, our suite of custom errors enhances the precision and clarity of error reporting in your Express.js application.

CustomError extends the native Error class, offering a structured approach to error handling. Its constructor, with optional parameters for a custom message and HTTP status, facilitates the creation of instances with specific details. The class ensures a unique identifier and allows explicit association of HTTP status codes. This tailored error-handling class enhances the precision of error communication and management within the application, providing developers with a valuable tool for addressing diverse scenarios.

// Custom Error for Unauthorized Access
class UnauthorizedError extends Error {
  constructor(message = 'Unauthorized Access') {
    super(message);
    this.name = 'UnauthorizedError';
    this.status = 401;
  }
}

// Custom Error for No Data Found
class NoDataError extends Error {
  constructor(message = 'No Data Found') {
    super(message);
    this.name = 'NoDataError';
    this.status = 404;
  }
}

// Custom Error for Schema Validation Error
class ValidationError extends Error {
  constructor(message = 'Schema Validation Error') {
    super(message);
    this.name = 'ValidationError';
    this.status = 422;
  }
}

// Custom Error for Duplicate Resource
class DuplicateError extends Error {
  constructor(message = 'Resource Already Exists') {
    super(message);
    this.name = 'DuplicateError';
    this.status = 409;
  }
}

// Custom Error for Invalid Input
class InvalidInputError extends Error {
  constructor(message = 'Invalid Input') {
    super(message);
    this.name = 'InvalidInputError';
    this.status = 400;
  }
}

// Custom Error for Rate Limit Exceeded
class RateLimitError extends Error {
  constructor(message = 'Rate Limit Exceeded') {
    super(message);
    this.name = 'RateLimitError';
    this.status = 429;
  }
}
Enter fullscreen mode Exit fullscreen mode

modified errorhandler middleware

app.use((err, req, res, next) => {
  // Default error response
  const errorResponse = {
    error: {
      message: err.message || 'Internal Server Error',
      status: err.status || 500,
    },
  };

  // Log the error (customize this based on your logging setup)
  console.error(err);

  // Send the error response to the client
  res.status(errorResponse.error.status).json(errorResponse);
})
Enter fullscreen mode Exit fullscreen mode

By adhering to the approaches outlined above, implementing the CustomError class provides a systematic and tailored means of managing errors in your Express.js application. The structured approach, with specific messages and HTTP status codes, enhances precision in error communication. This practice fosters a more organized and comprehensible error-handling strategy. As we delve into asynchronous error handling in the upcoming blog, the foundation laid by these custom errors positions us well to navigate and manage potential challenges seamlessly, ensuring a robust and resilient error-handling mechanism throughout our application.

Top comments (0)