What is Error Handler
Error handler is responsible of identifying and handling runtime issues.
Express.js comes pre-configured with a built-in Error Handler by default.
Error Handlers In ExpressJS🚀
Whenever a server error occurs, Express.js detects it and, unless you have a custom error handler, uses its built-in error handler to send a response to the client with the error message. Not only is Express.JS keen to handler errors properly but also to correctly empty away any unused resources when the application starts up again.
How to write Custom Error Handler Middleware in Express.js using JavaScript🚀
1. Create Custom ErrorHandler middleware
// ErrorHandler.js
const ErrorHandler = (err, req, res, next) => {
console.log("Middleware Error Hadnling");
const errStatus = err.statusCode || 500;
const errMsg = err.message || 'Something went wrong';
res.status(errStatus).json({
success: false,
status: errStatus,
message: errMsg,
stack: process.env.NODE_ENV === 'development' ? err.stack : {}
})
}
export default ErrorHandler
NOTE: _ err.stack
shows the exact file and line number the error occured. This is only needed in developement mode to debug your code. It becomes dangerous when your project structure is exposed on production_
2. Attach Custom Error Handler as The Last Middleware to Use
// index.js (Server Entery File)
import { AuthRoute, CategoryRoute, HomeRoute, PostRoute, UserRoute } from "./routes/index.routes.js";
import ErrorHandler from "./middlewares/ErrorHandler.js";
// init app
const app = express();
// MIDDLEWARES
app.use("/", HomeRoute);
app.use("/user", verifyAccessToken, UserRoute);
app.use("/categories", CategoryRoute);
app.use("/posts", PostRoute)
app.use("/auth", AuthRoute);
// ERROR HANDLER MIDDLEWARE (Last middleware to use)
app.use(ErrorHandler)
3. How to Call the ErrorHandler
to call the ErrorHandler, Use the next()
in Express.
The next function is a function in the Express router which, when invoked, executes the middleware succeeding the current middleware.
app.use("/books", (req, res, next) => {
try{
// code block to be executed
}catch(err){
next(err);
}
})
Sample Error Response on Production
Sample Error Response in developement✔
Why Should I Create Custom ErrorHandler instead of using the built-in ErrorHandler👀
You might want to create a custom errorhandler for a number of reasons.
For instance, some projects don't set NODE_ENV to "production" during the production stages. If error is not handled correctly, this could result in the disclosure of sensitive information about the server.
Other projects needs different error object format be sent at different points.
As a developer, It is very important to handler all error correctly to avoid crushing your APP anytime an error occurs.
Bentil here🚀
If you like my content, you can support me here to keep up the work.👇
Let me know your questions or suggestions in the comment box below
Top comments (17)
Hey, thank you for this article. Do you mind sharing how your routes file is structured? The way mine is structured is that all the routes are on the router object and I export that route object and within app.js I have
I like how yours is explicit, I'm not sure how I can import each route by name the way you have it setup.
Thanks in advance.
Project Structure
Routes Structure:
This is how each route looks like
For easy export and import, I have created the
index.route.js
to export all routes from a single fileSo I can easily import the routes like this
Instead of importing them from their separate files.
This is a typical backend repo of mine. You can check it out
github.com/qbentil/funchat-backend
Thank you for sharing that, I'm going to separate my routes like that too. If I may, I seen a video of someone who had a ".env" file in the root directory and a config folder located in "/src/config" and within that config.js file, they basically copied the variables in ".env" and pasted them in "config.js" and exported them to be used in their code.
Right now, I only have the ".env" file and access the variables located within it using the "process.env" object within my code, example: "process.env.HOST"
I like the idea of accessing the environment variables like so; "config.HOSTNAME" but, I find it redundant and time consuming to always update "/configs/config.js" every time we add a new variable to ".env"
Is that what you are doing or have you found a way where every time you add/remove a new variable in ".env" it automatically adds/removes the variable in "/configs/config.js"?
by the way, I just checked out your GitHub Portfolio briefly and noticed a minor typo. In your "ABOUT ME" you have "(Coud Storage)" I think you meant, "(Cloud Storage" -- tryna help hope that's not annoying to point out.
I also use the same approach you are using now.
I access the env variables through the
process.env.NAME
Thank you very much for the feedback on my readme. I really Appreciate.🥰🎉
I will check it out asap
Can you show me how I would go about implementing this error handler with try catch in the following GET route? The route makes a query to a database table named images and sends the data over to the frontend. If there is some kind of error in accessing the data, I'm not sure how to go about grabbing the database error. I am using "throw new Error" but that only stops the program on its tracks. I want to be able to get the error in JSON and send the error to the user if possible.
app.get("/", (req, res) => {
dbConnection.query("SELECT * FROM images WHERE user_id = ?", [1], (err, result) => {
if(!err) res.render("index", {images:result})
else throw new Error(err)
})
})
Hello Miguel, You can put it this way if you have your errorhandler middleware in place
I hope this help☺
Even if we don't use a try and catch and even if we don't use next(), the errors in the route are accessible in error handler middleware.
What is the reason for using the try and catch?
I would also be grateful if you could tell me how to customize the errors of each root in itself.I mean how to set for example error message and or name in every route.
Without the next() The errors will not be handled by your error Handler middleware. It will be handled by Express framework’s default error handler
Errors that are created by asynchronous functions that are called from route handlers, need to be handled differently. The error from asynchronous functions are not handled by the default error handler in Express which can result in crashing the entire App. Putting then in a try catch block will help you handle those errors separately using you custom error handler
This was simple and straightforward. Thanks for sharing.
I am glad you like it✨🚀
This piece was very helpful.
Thank youu
Hey, very very thank you for this article. This helps me a lot and finding you a good guy.. keep sharing and shining 🌟🌟
Hey Krishna
Thank you for the positive feedback.
I'm glad you found this helpful🙌
I will try it. N thanks to the creator of d content. You putting out priceless information for free..... 💯. Continue the good work.
You are most welcome
I'm glad you like it