1

I have an Expressjs route which does a db INSERT (using Sequelize) based on some JSON Body params in the request. The bodyParser middleware does a JSON-schema validation on the body and returns an error if it doesn't validate.

The issue here is that something in bodyparser is executing asynchronously, and I'm getting errors such as null values being inserted into the DB (even after a failed validation), and Headers already returned to client errors.

How to best fix this?

The route:

var bodyParser = json_validator.with_schema('searchterm');
router.post('/', bodyParser, function (req, res, next) {
    Searchterm.findOrCreate({
        where: {searchstring: req.body.searchstring},
        defaults: {funnystory: req.body.funnystory},
        attributes: ['id', 'searchstring', 'funnystory']
    }).spread((searchterm, created) => {
        if (created) {
            res.json(searchterm);
        } else {
            res.sendStatus(409);
        }
    }).catch(next);
});

The middleware:

var ajv = new Ajv({allErrors: true});
var jsonParser = bodyParser.json({type: '*/json'});

module.exports.with_schema = function(model_name) {
    let schemafile = path.join(__dirname, '..', 'models', 'schemas', model_name + '.schema.yaml');
    let rawdata = fs.readFileSync(schemafile);
    let schema = yaml.safeLoad(rawdata);
    var validate = ajv.compile(schema);
    return function(req, res, next) {
        jsonParser(req, res, next);
        if (!validate(req.body)) {
            res.status(400).send(JSON.stringify({"errors": validate.errors}));
        }
    }
};
Drew
  • 15
  • 3

1 Answers1

0

Your middleware calls next too early; change:

return function(req, res, next) {
    jsonParser(req, res, next);
    if (!validate(req.body)) {
        res.status(400).send(JSON.stringify({"errors": validate.errors}));
    }
}

to:

return function(req, res, next) {
    if (!validate(req.body)) {
        res.status(400).send(JSON.stringify({"errors": validate.errors}));
    }
}

and your route definition to:

router.post('/', jsonParser, bodyParser, function (req, res, next) { ... });
grim
  • 6,669
  • 11
  • 38
  • 57