I'm new to the Express, and I'm trying to apply some error handling at the top level.
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.