Express and MongoDB, how to manualy throw the error in the route controllers?

Viewed 19

I'm new to the Express, and I'm trying to apply some error handling at the top level.

This is how my project setup so far

In my controllers file, I have a controller to get all tours.

exports.getAllTours = async (req: Request, res: Response) => {
  //Execute query
  const features = new APIFeatures(Tour.find(), req.query)
    .filter()
    .sort()
    .limitFields()
    .paginate();

  // Endpoint: http://localhost:8000/api/v1/tours
  // Enter a wrong URL here will not even trigger the console.log function.
  // But I want to throw the error right here, not in the app.all('*')
  console.log("features", features);

  if (!features) {
    throw new NotFoundError("Tours Not Found");
  }

  //same problem here.
  const tours = await features.query;
  console.log("tours", tours.length);

  if (!tours) {
    throw new NotFoundError("Tours Not Found");
  }

  res.status(200).json({
    status: "success",
    result: tours.length,
    data: {
      tours,
    },
  });
};

I have a CustomError class that extends the Error class like this.

const httpStatusCode = require("./httpStatusCode");

class CustomError extends Error {
  constructor(message: string, statusCode: number, description: string) {
    super(description);

    //Object.setPrototypeOf(this, new.target.prototype);
    this.message = message;
    this.statusCode = statusCode;
  }
}
module.exports = CustomError;


class NotFoundError extends CustomError {
  constructor(message, statusCode) {
    super(message, statusCode);
    this.message = message;
    this.statusCode = httpStatusCode.NOT_FOUND;
  }
}

module.exports = NotFoundError;

Also an error handling middleware:

import { NextFunction, Request, Response, ErrorRequestHandler } from "express";

module.exports = (
  err: Error,
  req: Request,
  res: Response,
  next: NextFunction
) => {
  err.statusCode = err.statusCode || 500;
  err.status = err.status || "error";
  res.status(err.statusCode).json({
    status: err.status,
    message: err.message,
  });
};

In the end, I use the errorHandler middleware in the app to catch all the errors. However, the problem is all the errors in the getAllTours controller will not be thrown, instead, they will be thrown in the app.all():

app.use("/api/v1/tours", tourRouter);
app.all("*", (req: Request, res: Response) => {
  throw new NotFoundError("Page Not Found");
  //next(new AppError(`Can't find ${req.originalUrl} on this server`, 404));
});

app.use(errorHandler);

I know since the endpoint has been changed and thrown in the app.all() make sense. But how can I manually throw an error in the getAllTours controller? I use express-async-error so I could use the throw keyword in the async function.

0 Answers
Related