I’m using node & express to make a server
but for some reason the error occurring in a router does not get handled & crashes the entire server:
Server.js:
import SubRouter from './routes/SubRouter.js';
import express from 'express';
const server = express();
server.use(express.json())
server.use('/sub', SubRouter);
server.get("/update", (req, res) => {
throw new Error("Testing") // This does not crash the server
});
// Handle Error
server.use((err, req, res, next) => {
console.error("Error Handled")
res.json({
error: err.message
})
})
server.listen(3000, () => {
console.log(`listening at 3000 ...`);
});
./routes/SubRouter.js:
import { Router } from "express";
const SubRouter = Router()
SubRouter.get("/update", async (req, res) => {
throw new Error("Testing") // This crashes the server
});
export default SubRouter
Error Log:
file:///.../routes/SubRouter.js:7 throw new Error("Testing") // This crashes the server ^ Error: Testing at file:///.../routes/SubRouter.js:7:11 at Layer.handle [as handle_request] (/.../node_modules/express/lib/router/layer.js:95:5) at next (/.../node_modules/express/lib/router/route.js:144:13) at Route.dispatch (/.../node_modules/express/lib/router/route.js:114:3) at Layer.handle [as handle_request] (/.../node_modules/express/lib/router/layer.js:95:5) at /.../node_modules/express/lib/router/index.js:284:15 at Function.process_params (/.../node_modules/express/lib/router/index.js:346:12) at next (/.../node_modules/express/lib/router/index.js:280:10) at Function.handle (/.../node_modules/express/lib/router/index.js:175:3) at router (/.../node_modules/express/lib/router/index.js:47:12)
I would use a try catch
but that defeats the purpose of having an Error handler middleware
Can someone please explain why the error is not getting handled?
2
Answers
I figured it out, The problem wasn't with router it was with
async
so I wrapped my function with anasyncHandler
like this:where
asyncHandler
is defined as follows:I generally wrap the code that may produce an error in
try...catch
block. When an error gets caught, I pass it to the error handler route usingnext(error)
.To use the
next
callback function, you need to add another parameter to your routes as shown below:This way you make sure all errors thrown inside your routes are caught by your error handling middleware. To improve this approach, I create a helper class which handles errors and produces more meaningful errors to pass to error handling middleware.
After that you can use these custom errors in your routes as such:
This is my own approach and it works pretty much fine. You can also outsource the error messages into another file such as
messages/errors.js
. So you can manage error messages in single file and multi-language them easily when needed.