I have a problem with my error handler like below:
export const errorHandler = (
error: Error,
req: Request,
res: Response,
next: (error: Error) => void,
) => {
console.log("TEST");
next(error);
}
It is very simple but I have a problem with launching it on errors, here is my index.js:
export const server = http.createServer(app);
const initServer = () => {
app.use(bodyParser.json({ limit }));
app.use(morgan("[:date[iso]] :method :url :status :response-time ms"));
app.use(express.json());
app.use(cors({ credentials: true, origin: true }));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(router);
app.use(errorHandler); //IS HERE
server.listen(PORT, () => {
logger.info(`Server running on port ${PORT}`);
});
};
initServer();
Can someone tell me why it is not working when I call an request when I set:
throw new Error("ERROR");
Thanks for any answer, thanks!
PS. router
file is here:
export const router = express.Router({ mergeParams: true });
router.get("/account/login", login);
//and more...
CodePudding user response:
If I am not mistaken you didnt import/require the error handler in your index.js
CodePudding user response:
you have to enclose your response within the errorHandler middleware... let me show you how I do this
I create a generic middleware which is used in every route
this is in Typescript, if you use only Javascript just remove the types (it's easy to port)
return async function (req: Request, resp: Response, next) {
try {
const response = await fn(req, resp, next);
resp.status(200).send(response);
} catch (e) {
// here you can handle the error the way you wish to
// I throw all my errors as ErrorObject ( a custom class)
// so I can send user formatted errors, you can implement this
// however you wish to
if (e instanceof ErrorObject) {
const error = e.json();
resp.status(e.statusCode).send(error);
} else next(e);
}
};
Now any of your route should use this middleware as follows
router.post(
"/your-route",
expressResponse((req, resp) => {
// do want you want
}),
);
CodePudding user response:
If you are using express 4.x or earlier, and you are using asynchronous route handlers, you need to catch any encountered errors and pass them explicitly to next()
in order for them to be processed by your error handler.
I have a helper function I use to wrap async handlers in my projects that looks like this:
/**
* Wrapper for async route handlers that passes Promise-based errors to next().
*
* NOTE: Starting with Express 5 (which is not released as of this note) exceptions
* in async middleware will be handled as expected, and this asyncMiddleware will
* no longer be needed.
*
* When an async route handler rejects a Promise, it is important that the
* Express error handler be invoked to end the request cleanly. This wrapper
* function supports the idiomatic:
*
* router.use('/path', asyncMiddleware(async(req, res) => {
* await db.save(); // permitted b/c we are async
* if (something_bad) {
* throw(...); // reject promise, and invokes Express error handler
* }
* return res.send({}); // resolve promise normally
* }
*/
export const asyncMiddleware =
fn => (req: Request, res: Response, next: NextFunction) => {
Promise.resolve(fn(req, res, next)).catch(next);
};