Handling error in express applications can be more challenging than building web applications and APIs
Building web applications or APIs with express.js is not difficult in my opinion. I think it is more difficult to handle errors, error status codes and error messages properly. Below, I’m going to list out a few techniques by which I handle errors in my express.js applications.
We need to understand middleware to handle errors if you want to apply the technique I am going to suggest. Simply, a middleware in express is a function that has access both the request and the response objects for a particular route. Additionally, they take in an argument next which is a function that gets called after the middleware function is executed.
Middleware example
In the above example, if you send a get request to /someroute route ‘Request made’ will be logged on the console.
Controllers and Middlewares
Controllers and Middlewares
The above image explains what is a controller and what is middleware. When a request is received on a particular route, middleware-1,2 and 3 gets called before the controller for that route is called. The controller can then send a response. However, the middleware function also has access to the response object, middleware can also send a response and close the request. So, you can assume that any middleware is a controller and any controller is a middleware.
For example, a middleware function to verify JWTs can be created. The middleware will verify if the token is valid. If it is invalid, the middleware will send an error response back to the client and close the request. The middlewares/controller after that JWT verification middleware will not be called in that case.
Project Structure
Express is an unopinionated web framework for building web applications using Node.JS. Since, it is an unopinionated web framework, the directory structure for organizing project is not strictly recommended by the framework creators. Below, I am going to show you the screenshot of my project structure which you can follow to organize your projects, however, you can follow your own structure if that feels right.
Project Structure
Function to create error objects
Inside utils/createError.js file, I have a function that takes in two things: a status code and an error message and returns an error object.
utils/createError.js
Centralized Error Handler in app.js
This is the main part of this story. We are going to make a middleware function that can accept error objects and if an error is received, it can send an error response to the client making the request. To do so, we are going to create 2 middleware functions. One of the middleware will get triggered if none of the routes above gets called and another will get triggered if any middleware/controller throws an error.
The structure of our app.js will look something like the following.
Middleware functions
Generally, all errors have a message property so, you can trust that there will be a message with error object in our error handling middleware. If in case there’s not one then, by default ‘Internal server error will be sent.’
How to trigger an error to utilize our centralized error handler?
Imagine that you have a controller that logs in users to the application. A high-level implementation example will be shown in the example here. On the bottom of this story, I will add a GitHub repository of an express application which will include all these applied on a real project.
Login and error handling example
This is how you can apply error handling practices in your express.js applications.
If you want to see a project with all these applied, go to this GitHub Repository and see the code in action.
Thank you for reading. I also write contents for my own website https://bigomega.dev. You can sign up for my newsletter.
A note In Plain English
Did you know that we have four publications and a YouTube channel? You can find all of this from our homepage at plainenglish.io — show some love by giving our publications a follow and subscribing to our YouTube channel!