sequelize: TypeError when running findOrCreate with some of the newest pg versions

What you are doing?

I try to run findOrCreate with where- and defaults- objects with the newest sequelize (4.4.2) and pg (7.0.2). Database doesn’t contain the instance I’m running this with (which would be the ‘Bar’ with id 11 in the example).

const Sequelize = require('sequelize');
const sequelize = new Sequelize('seq_test', 'Perttu', null, {
  host: 'localhost',
  dialect: 'postgres',
  port: 5432
});

var Foo = sequelize.define('Foo', {
  id: { type: Database.DataTypes.INTEGER, autoIncrement: true, primaryKey: true },
  content: Database.DataTypes.TEXT
});

var Bar = sequelize.define('Bar', {
  id: { type: Database.DataTypes.INTEGER, autoIncrement: true, primaryKey: true },
  name: Database.DataTypes.STRING
});

Foo.belongsTo(Bar);

const bar = {
  name: 'Test Bar',
  id: 11
};

sequelize.sync()
  .then(() => Bar.findOrCreate({ where: { id: bar.id }, defaults: { id: bar.id, name: bar.name }})
  .then((result, created) => {
    console.log(result);
  }).catch(err => {
    console.error(err);
  }));

What do you expect to happen?

I expected that the new ‘Bar’ -instance would be created and inserted into the database, and returned to me without any errors.

What is actually happening?

Somehow there seems to be an undefined variable running through the code. The new instance is inserted into the database, but the code bumps into an error.

TypeError: Cannot read property '0' of undefined
    at query.catch.then.then.queryResult (/Users/Perttu/PepronProjects/sequelizeTest/node_modules/sequelize/lib/dialects/postgres/query.js:112:17)
    at tryCatcher (/Users/Perttu/PepronProjects/sequelizeTest/node_modules/bluebird/js/release/util.js:16:23)
    at Promise._settlePromiseFromHandler (/Users/Perttu/PepronProjects/sequelizeTest/node_modules/bluebird/js/release/promise.js:512:31)
    at Promise._settlePromise (/Users/Perttu/PepronProjects/sequelizeTest/node_modules/bluebird/js/release/promise.js:569:18)
    at Promise._settlePromise0 (/Users/Perttu/PepronProjects/sequelizeTest/node_modules/bluebird/js/release/promise.js:614:10)
    at Promise._settlePromises (/Users/Perttu/PepronProjects/sequelizeTest/node_modules/bluebird/js/release/promise.js:693:18)
    at Async._drainQueue (/Users/Perttu/PepronProjects/sequelizeTest/node_modules/bluebird/js/release/async.js:133:16)
    at Async._drainQueues (/Users/Perttu/PepronProjects/sequelizeTest/node_modules/bluebird/js/release/async.js:143:10)
    at Immediate.Async.drainQueues (/Users/Perttu/PepronProjects/sequelizeTest/node_modules/bluebird/js/release/async.js:17:14)
    at runCallback (timers.js:672:20)
    at tryOnImmediate (timers.js:645:5)
    at processImmediate [as _immediateCallback] (timers.js:617:5)

I run at this error with my other project when I updated dependencies to the latest versions (same versions as in this example). Previously it’s been working fine, and when downgrading the node-postgres (pg) to older versions (i.e. 6.4.0), the example above works fine. Pg version 7.0.0 resuts to the same error.

Please note that this works fine when the database finds the object. If I run the same code again, the database can find the instance and returns it nicely. The problem occurs when the instance has to be created into the database during the transaction.

I know that there was some breaking changes that caused problems to sequelize when pg released the version 7 but I didn’t find any issues related to this particular problem.

Dialect: postgres Database version: 9.6 Sequelize version: 4.4.2

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 38
  • Comments: 17 (3 by maintainers)

Commits related to this issue

Most upvoted comments

I had the same issue and fixed it by downgrading my pg version to @6.4.1, maybe that’s also your issue??

Same error with pg: 7.2 & sequelize 4.7

I downgraded my PG to version 6.4.1 and it works!

Same - pg 7, executing raw query

TypeError: Cannot read property '0' of undefined
    at query.catch.then.then.queryResult (/Users/contra/Projects/staeco/node_modules/sequelize/lib/dialects/postgres/query.js:112:17)
    at tryCatcher (/Users/contra/Projects/staeco/node_modules/bluebird/js/release/util.js:16:23)
    at Promise._settlePromiseFromHandler (/Users/contra/Projects/staeco/node_modules/bluebird/js/release/promise.js:512:31)
    at Promise._settlePromise (/Users/contra/Projects/staeco/node_modules/bluebird/js/release/promise.js:569:18)
    at Promise._settlePromise0 (/Users/contra/Projects/staeco/node_modules/bluebird/js/release/promise.js:614:10)
    at Promise._settlePromises (/Users/contra/Projects/staeco/node_modules/bluebird/js/release/promise.js:693:18)
    at Async._drainQueue (/Users/contra/Projects/staeco/node_modules/bluebird/js/release/async.js:133:16)
    at Async._drainQueues (/Users/contra/Projects/staeco/node_modules/bluebird/js/release/async.js:143:10)
    at Immediate.Async.drainQueues (/Users/contra/Projects/staeco/node_modules/bluebird/js/release/async.js:17:14)
    at runCallback (timers.js:672:20)
    at tryOnImmediate (timers.js:645:5)
    at processImmediate [as _immediateCallback] (timers.js:617:5)

Same here. Sequelize 4.8.4 and pg 9.6.4. It seems that the problem is with the abstract/query-generator.

`if (this.dialect.supports.EXCEPTION && options.exception) { // Mostly for internal use, so we expect the user to know what he’s doing! // pg_temp functions are private per connection, so we never risk this function interfering with another one. if (semver.gte(this.sequelize.options.databaseVersion, ‘9.2.0’)) { // >= 9.2 - Use a UUID but prefix with 'func’ (numbers first not allowed) const delimiter = ‘$func_’ + uuid.v4().replace(/-/g, ‘’) + ‘$’;

    options.exception = 'WHEN unique_violation THEN GET STACKED DIAGNOSTICS sequelize_caught_exception = PG_EXCEPTION_DETAIL;';
    valueQuery = 'CREATE OR REPLACE FUNCTION pg_temp.testfunc(OUT response <%= table %>, OUT sequelize_caught_exception text) RETURNS RECORD AS ' + delimiter +
      ' BEGIN ' + valueQuery + ' INTO response; EXCEPTION ' + options.exception + ' END ' + delimiter +
      ' LANGUAGE plpgsql; SELECT (testfunc.response).*, testfunc.sequelize_caught_exception FROM pg_temp.testfunc(); DROP FUNCTION IF EXISTS pg_temp.testfunc()';
  } else {
    options.exception = 'WHEN unique_violation THEN NULL;';
    valueQuery = 'CREATE OR REPLACE FUNCTION pg_temp.testfunc() RETURNS SETOF <%= table %> AS $body$ BEGIN RETURN QUERY ' + valueQuery + '; EXCEPTION ' + options.exception + ' END; $body$ LANGUAGE plpgsql; SELECT * FROM pg_temp.testfunc(); DROP FUNCTION IF EXISTS pg_temp.testfunc();';
  }
}`

This block of code will test with a plpgsql function if a record insert will fail and return the exception in a column called sequelize_caught_exception. The problem is that the DROP FUNCTION will avoid the return of the record from SELECT * FROM pg_temp.testfunc().

Actually, the only fix i found is to remove the DROP FUNCTION IF EXISTS pg_temp.testfunc() at the end of the statement.

I think a better fix is possible.

I moving from Mysql to Postgres and I am getting this same error not only on this but on using enums as well. I guess I will downgrade to @6.4.1

i have the same issue with Dialect: postgres Database version: 9.6 Sequelize version: 4.4.2

const Skill = sequelize.define('Skill', {
  id: {
    type: DataTypes.INTEGER,
    autoIncrement: true,
    primaryKey: true,
  },
  name: {
    type: DataTypes.STRING,
    allowNull: false,
  },
}, {
  indexes: [
    {
      unique: true,
      fields: ['name'],
    },
  ],
});

const [s] = Skill.findOrCreate({
        where: {
          name: skill,
        },
        logging: true,
      });
console.log(s);

when row exists, it works ok, but when not, it i get an error

TypeError: Cannot read property '0' of undefined
at query.catch.then.then.queryResult (/home/usr/project/node_modules/sequelize/lib/dialects/postgres/query.js:112:17)
at tryCatcher (/home/usr/project/node_modules/bluebird/js/release/util.js:16:23)
at Promise._settlePromiseFromHandler (/home/usr/project/node_modules/bluebird/js/release/promise.js:512:31)
at Promise._settlePromise (/home/usr/project/node_modules/bluebird/js/release/promise.js:569:18)
at Promise._settlePromise0 (/home/usr/project/node_modules/bluebird/js/release/promise.js:614:10)
at Promise._settlePromises (/home/usr/project/node_modules/bluebird/js/release/promise.js:693:18)
at Async._drainQueue (/home/usr/project/node_modules/bluebird/js/release/async.js:133:16)
at Async._drainQueues (/home/usr/project/node_modules/bluebird/js/release/async.js:143:10)
at Immediate.Async.drainQueues (/home/usr/project/node_modules/bluebird/js/release/async.js:17:14)
at runCallback (timers.js:781:20)
at tryOnImmediate (timers.js:743:5)
at processImmediate [as _immediateCallback] (timers.js:714:5)

it seems to be an issue with generated query, which returns nothing:

Executing (f76a3a60-104e-4c24-8e72-e845711cf176): START TRANSACTION;
Executing (f76a3a60-104e-4c24-8e72-e845711cf176): SELECT "id", "name", "createdAt", "updatedAt" FROM "Skills" AS "Skill" WHERE "Skill"."name" = 'repair door' LIMIT 1;
Executing (f76a3a60-104e-4c24-8e72-e845711cf176): CREATE OR REPLACE FUNCTION pg_temp.testfunc(OUT response "Skills", OUT sequelize_caught_exception text) RETURNS RECORD AS $func_72ac195e06dd47fea332e518204c4cf7$ BEGIN INSERT INTO "Skills" ("id","name","createdAt","updatedAt") VALUES (DEFAULT,'repair door','2017-07-26 07:01:01.398 +00:00','2017-07-26 07:01:01.398 +00:00') RETURNING * INTO response; EXCEPTION WHEN unique_violation THEN GET STACKED DIAGNOSTICS sequelize_caught_exception = PG_EXCEPTION_DETAIL; END $func_72ac195e06dd47fea332e518204c4cf7$ LANGUAGE plpgsql; SELECT (testfunc.response).*, testfunc.sequelize_caught_exception FROM pg_temp.testfunc(); DROP FUNCTION IF EXISTS pg_temp.testfunc();
Executing (f76a3a60-104e-4c24-8e72-e845711cf176): COMMIT;

because transaction works and data is inserted correctly