Thanks to Gravity for making this blog possible. Make sure you subscribe him for great dev content.
Errors that occur in synchronous code inside route handlers and middleware require no extra work. If synchronous code throws an error, then Express will catch and process it.
The following code will handle all the synchronous code. This means that each operation must wait for the previous one to complete before executing
By default express comes with error handler.
const express = require('express')
const app = express()
const port = 3000
app.get('/', (req, res) => {
res.status(200).send('Hello World!')
})
// Error handler for synchronous errors
// This should be the last middleware in the chain
app.use((err, req, res, next) => {
console.error(err.stack)
res.status(500).send('Something broke!')
})
app.listen(port, () => {
console.log(`Example app
listening on port ${port}`)
})
But Most of our backend consists of some db operations and is always asynchronous. This means you can move to another task before the previous one finishes.
π€¨ So how to handle Asynchronous error on express ?
One simple solution is to use try/catch and call next() on catch block.
By calling next() we indicate express to catch the error and respond accordingly.
The modified version of route will be.
app.get('/', (req, res, next) => {
try {
// some db asyncrhonous operations
res.status(200).send('Hello World!')
}
catch(error) {
next(error)
}
})
The next(error) will call our default error handling middleware and our result will be something broke! when error occurs.
But our app will not consists just one route. It would be just growing and we don't want to miss any errors that may suprise us in the future.
We will make something interesting without try/catch.
So we will create a promiseHandler function where we handle every asyncrhonous ( ideally a promise ) and call next() on reject.
In one line
const promiseHandler = () => (req, res, next) => {
Promise.resolve(fn(req, res, next)).catch(next)
}
// and route becomes
app.get('/', promiseHandler (async (req, res, next) => {
// some db asyncrhonous operations
res.status(200).send('Hello World!')
}))
This promise handler function takes a async function as argument and resolve when successfull or call next as a callback function when there is a error.
To hack away and test with some errors , use the following repository. nodejs-error-handler
For my typescript guys out there your promise handler function will be
import { NextFunction, Request, Response } from "express";
type fnType = (req : Request, res : Response, next : NextFunction) => void;
const promiseHandler = (fn: fnType) =>
(req : Request, res : Response, next : NextFunction) => {
Promise.resolve(fn(req , res , next)).catch(next)
}
export default promiseHandler
If you're interested in nodejs you may wanna know , Mistakes I made in Nodejs When I started
If you're starting with angular you may also want to know the mistakes I made in angular. Learn More
πΈ Are you a budding web developer and in need of some cool css websites to learn from Visit Colors & Design
And If you like these type of small articles to boost your knowledge, don't forget to follow on dev.to, It motivates to write more and contribute open source.
π Peace !
Try Our new product for free!
DocsAI - Create AI support agents with your documents in the most affordable price, starts at 0$. Don't need a bot , but need ai help on your docs just upload and start chating !
Using for a company ? Check out our pricing Just contact me for personalized pricing !
Top comments (2)
thanks so much
Hope it helps!