fanhats
fanhats

Reputation: 797

A way to prevent highly nested code in Sequelize for error handling?

I have a form and when something doesn't go right after submission, I want to be able to give the user specific error messages. I am using Sequelize as my ORM, and the promises returned are getting a bit messy with all the nested code.

For instance, if we have two models to update: User and Photo:

models.User.find({where: {name: 'bob' }}).then(function(user) {
    if(user) {
        user.updateAttributes({email: email}).then(function(user) {
            models.Photo.find({where: { hash: hash}}).then(function(photo) {
               if(photo)
                   res.json({"message":"updated"});
               else
                   res.status(404).json({"error": "Could not find Photo"});
            }).catch(err) {
               res.status(500).json({"error": err});
            });
        }).catch(function(err) {
            res.status(500).json({"error": err});
        });
    } else {
        res.status(404).json({"error": "Could not find user"});
    } 
}).catch(function(err) {
    res.status(500).json({"error": err});
});

And if I have 10 fields in the form to update, all the nested code can become overbearing.

What recommendations can be given if I wish to have specific error descriptions, but also more readable code? Would it be possible to capture all the 404 and 500 errors in one code block instead of breaking them up like I have?

Upvotes: 6

Views: 1910

Answers (1)

srlm
srlm

Reputation: 3226

You can make use of promise chaining and a helper method to reduce your code to a series of 3 .thens and a single .catch:

function notFoundError(model) {
    var e = new Error('Could not find ' + model);
    e.statusCode = 404;
    throw e;
}

models.User
    .find({where: {name: 'bob'}})
    .then(function (user) {
        if (user) {
            return user.updateAttributes({email: email});
        } else {
            notFoundError('user');
        }
    })
    .then(function (user) {
        return models.photos.find({where: {hash: hash}});
    })
    .then(function (photo) {
        if (photo)
            res.json({"message": "updated"});
        else
            notFoundError('photo');
    })
    .catch(function (err) {
        if (err.statusCode) {
            res.status(err.statusCode);
        } else {
            res.status(500);
        }
        res.json({'error': err.message});
    });

Upvotes: 10

Related Questions