Reputation: 435
I am trying to use next() in express to pass error to custom middleware in a route below:
app.post("/api/persons", (req, res) => {
const findPerson = Person.findOne({ name: req.body.name });
if (findPerson.length) {
res.status(404).json({ error: "Name already exists" });
} else if (req.body && req.body.name && req.body.number) {
const person = new Person({
name: req.body.name,
number: req.body.number,
});
person
.save()
.then((savedPerson) => {
console.log("saved successfully.");
res.json(savedPerson).end();
})
.catch((err) => next(err));
app.use(morgan("tiny"));
} else {
res.status(404).json({ error: "Name or number missing" });
}
});
I have defined the middleware function as below:
const errorHandler = (error, request, response, next) => {
console.error(error.message);
if (error.name === "CastError") {
return response.status(400).send({ error: "malformatted id" });
}
next(error);
};
app.use(errorHandler);
I am adding this middleware to at the very last of file, after all other app.use(). But I keep receiving reference error as below:
UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch().
Even though I am clearly using catch block, it seems to throw error. I tried adding the definition of error handler to the top but it still shows the same error.
Upvotes: 2
Views: 1138
Reputation: 57105
Change
app.post("/api/persons", (req, res) => { // next is missing here
// ..///
});
To
app.post("/api/persons", (req, res, next) => { // add next here
// ../// next(err); // call next with error now
});
Since promises automatically catch both synchronous errors and rejected promises, you can simply provide next as the final catch handler and Express will catch errors, because the catch handler is given the error as the first argument.
Read - https://expressjs.com/en/guide/error-handling.html
For errors returned from asynchronous functions invoked by route handlers and middleware, you must pass them to the next() function, where Express will catch and process them.
function errorHandler (err, req, res, next) {
if (res.headersSent) {
return next(err)
}
res.status(500)
res.render('error', { error: err })
}
Upvotes: 3