1

I hope you're having a good day.

First of all, I'm sorry if you think this is a stupid question but I'm genuinely curious as to what you do in your own projects or let's say in a production environment.

So I've been using express for quite some time now and I usually send my errors back to the client manually in each request handler, when something isn't expected or an error occurs as such:

userController.js

const ERRORS = require('../utils/errors.js');

const userController = {

    updateUser: (req, res) => {
        let id = req.params.id;
        
        if(!validUserId(id))
            return res.status(400).json({error:ERRORS.INVALID_USER_ID});

        let user = await findUserById(id);

        if(!user)
            return res.status(404).json({error: ERRORS.USER_NOT_FOUND});
        
        try {
            let updatedUser = await updateUser(id);

            return res.status(201).json({data: updatedUser});
        }
        catch(e){
            return res.status(500).json({error:ERRORS.FAILED_UPDATE_USER});
        }
    }
}

As you can see this can get really unmanageable really quickly and just overall makes the code less readable, especially if you're doing this for every request.

My question here is: does using a catch all global error handler middleware slow down express or create potential problems I'm not aware of or is it actually a suggested approach by some?

The code would then look like:

errorHandler.js

    const errorHandler = (err, req, res, next) => {
        // assume this function returns details about an error given an error message
        // such as if the custom error message is USER_NOT_FOUND
        // => it returns {status:404, message: "User not found"}
        const {status, message} = getErrorDetails(err.message);

        if(!res.headersSent)
            res.status(status).json({error: message})
    }

userController.js

const ERRORS = require('../utils/errors.js');

const userController = {
    
    updateUser: (req, res) => {
        let id = req.params.id;
        
        if(!validUserId(id))
            throw new Error(ERRORS.INVALID_USER_ID);

        let user = await findUserById(id);

        if(!user)
            throw new Error(ERRORS.USER_NOT_FOUND);
        
        try {
            let updatedUser = await updateUser(id);

            return res.status(201).json({data: updatedUser});
        }
        catch(e){
            throw new Error(ERRORS.FAILED_UPDATE_USER);
        }
    }
}

Thank you. Your insights are very much appreciated.

Jeffrey
  • 75
  • 9
  • 1
    An error handling middleware is preferred because you manage everything in one place. You may eventually want to add logging, or you may want to send a notification to slack for some error codes. This makes everything easier. – Someone Special Nov 09 '21 at 22:44
  • @SomeoneSpecial yeah exactly having everything in one place just makes it easier to manage. Also that's a really good point about slack, I've never thought of it that way. – Jeffrey Nov 09 '21 at 22:47

0 Answers0