Search code examples
javascriptnode.jspromisesequelize.jsbluebird

accidentally swallowing not-null constraint in Sequelize (probably error-handling in bluebird promises screwup)


(Note: likely a dumb beginner question),

I'm new to Sequelize and to promises in JS --- and in the course of testing some code that I would expect to throw an error, instead I see a silent failure.

Here's the relevant code (this is using express for a web server, and with a sqllite back-end on disk)

const User = sequelize.define('user', {
  "firstName": {type: Sequelize.STRING},
  "lastName": {type: Sequelize.STRING},
  "id": {type: Sequelize.INTEGER, autoIncrement: true, primaryKey: true},
  "gym": {type: Sequelize.STRING, allowNull: false}
});

function addUser(first, last, gym){
  return User.sync().then(() => User.create({"firstName": first, "lastName": last, "gym": gym}))
}

function testBlowUpAdd(req, res){
  addUser(null, null, null).then(res.send("added user")).catch(e => res.send(e.toString()));
}

app.get("/testboom", testBlowUpAdd);

When I hit that endpoint, I expect to see whatever error Sequelize throws when you violate a database constraint. Instead, I see "added user." However, when I go looking into the database, as expected, my all-null row doesn't appear.

So clearly, I'm accidentally swallowing the error. Almost certainly because I don't understand how error-handling happens in promises. I would have thought that the call to addUser would throw, and that as a result the promise mechanism wouldn't call the handler in then() and would call the handler in catch()... but evidently that's incorrect?


Solution

  • The res.send() function is being called immediately when the promise is being setup, the return value of res.send() is being passed as the argument to .then().

    The .then argument should be a function, so it can run later when the promise resolves.

    function testBlowUpAdd(req, res){
      addUser(null, null, null)
        .then(user => res.send("added user"))
        .catch(e => res.send(e.toString()));
    }