Node-mssql: TypeError => 'validate' of undefined (prototype leakage)

Created on 30 Jan 2016  路  22Comments  路  Source: tediousjs/node-mssql

Hi all.

Here is a part of my code:

var importDb = function() {
  sql.connect(connectionString).then(function() {
    console.log('connected');   ///////////////////////////////////// UNTIL HERE IS OK
    var query = 'SELECT TOP 10 * FROM ' + mRecord.view_path + ';'; // I'M SURE QUERY IS OK
    console.log('starting, with query: ' + query);
    var request = new sql.Request();
    request.query(query).then(function(recordset) {
      console.log('data successfully retrieved');  ///////////////// NEVER GETS EXECUTED
    }).catch(function(err) {
      console.log(err);
    });
  });
}

OK, to be honest, when I create a completely new project with this snippet, everything works perfectly but in my development project, the line where is .then(recordset) is throwing the error:

[TypeError: Cannot read property 'validate' of undefined]

Do you have a hint why? If you need more info, feel free to ask.

Node versions (nvm):
5.1.0
5.3.0
5.5.0

discussion

All 22 comments

Could you please post a whole stack?

I didn't get the stack "out of the box" so I did this:

.catch(function(ex) {
    console.log(ex, ex.stack.split("\n"));
});

and got this:

[TypeError: Cannot read property 'validate' of undefined] [ 'TypeError: Cannot read property \'validate\' of undefined',
  '    at Request.validateParameters (/home/username/Projects/ds/node_modules/tedious/lib/request.js:160:35)',
  '    at Request.transformIntoExecuteSqlRpc (/home/username/Projects/ds/node_modules/tedious/lib/request.js:93:16)',
  '    at Connection.execSql (/home/username/Projects/ds/node_modules/tedious/lib/connection.js:757:15)',
  '    at /home/username/Projects/ds/node_modules/mssql/lib/tedious.js:991:77',
  '    at Pool.dispense [as _dispense] (/home/username/Projects/ds/node_modules/mssql/node_modules/generic-pool/lib/generic-pool.js:309:14)',
  '    at Pool.acquire (/home/username/Projects/ds/node_modules/mssql/node_modules/generic-pool/lib/generic-pool.js:387:8)',
  '    at Request._acquire (/home/username/Projects/ds/node_modules/mssql/lib/main.js:1137:37)',
  '    at Request.TediousRequest.query (/home/username/Projects/ds/node_modules/mssql/lib/tedious.js:713:21)',
  '    at Request._query (/home/username/Projects/ds/node_modules/mssql/lib/main.js:1517:54)',
  '    at /home/username/Projects/ds/node_modules/mssql/lib/main.js:1477:24' 

I'm not able to reproduce the issue. The error you get is because of invalid type of an input parameter. It's happening on this line. But the request you're creating in your sample has no parameters. Are you sure you're getting this error with exactly this sample code?

Yeah, I'm also inspecting the code and nothing for now... I'll try to rewrite the part with mssql and let you know.

Thank you very much for your time.

Strange thing is, this worked beautifully until few days ago. :)

I found the error. I was commenting out module by module and after commenting out these two functions in my custom module, everything worked:

/* get and sort keys from object */
Object.prototype.keysSorted = function(o) {
  return Object.keys(o).sort();
};

/* get first key from object */
Object.prototype.getFirstKey = function(o) {
  for (var a in o) return a;
};

I still don't understand what the problem was.

Any update on the why? I've just run into the same problem, adding function to Object.prototype breaks my mssql js.

I am getting this error

 TypeError: Cannot read property 'validate' of undefined
mdip_p1-0     at Request.validateParameters (/home/adm_s2u/mdip/node_modules/tedious/lib/request.js:154:35)
mdip_p1-0     at Connection.callProcedure (/home/adm_s2u/mdip/node_modules/tedious/lib/connection.js:780:15)
mdip_p1-0     at /home/adm_s2u/mdip/node_modules/mssql/lib/tedious.js:1319:33
mdip_p1-0     at /home/adm_s2u/mdip/node_modules/generic-pool/lib/generic-pool.js:376:9
mdip_p1-0     at Connection.<anonymous> (/home/adm_s2u/mdip/node_modules/mssql/lib/tedious.js:383:24)
mdip_p1-0     at Connection.g (events.js:260:16)
mdip_p1-0     at emitNone (events.js:67:13)
mdip_p1-0     at Connection.emit (events.js:166:7)
mdip_p1-0     at Connection.processedInitialSql (/home/adm_s2u/mdip/node_modules/tedious/lib/connection.js:663:19)
mdip_p1-0     at Connection.message (/home/adm_s2u/mdip/node_modules/tedious/lib/connection.js:1150:21)
mdip_p1-0     at Connection.dispatchEvent (/home/adm_s2u/mdip/node_modules/tedious/lib/connection.js:519:45)
mdip_p1-0     at MessageIO.<anonymous> (/home/adm_s2u/mdip/node_modules/tedious/lib/connection.js:439:23)
mdip_p1-0     at emitNone (events.js:67:13)
mdip_p1-0     at MessageIO.emit (events.js:166:7)
mdip_p1-0     at ReadablePacketStream.<anonymous> (/home/adm_s2u/mdip/node_modules/tedious/lib/message-io.js:92:15)
mdip_p1-0     at emitOne (events.js:77:13)

Please help

@sunojvijayan - Do you have anything defined in Object.prototype? Something like this:

/* get and sort keys from object */
Object.prototype.keysSorted = function(o) {
  return Object.keys(o).sort();
};

/* get first key from object */
Object.prototype.getFirstKey = function(o) {
  for (var a in o) return a;
};

no

also getting this error, still can't figure it out, i'm not adding anything to Object.prototype but i do have this in my code

Object.keys(parameters).forEach(paramName => { request.input(paramName, parameters[paramName]); });

The only way I've managed to find my fix is that you create a backup of your project and start commenting out parts of your project and find the line which is causing trouble. Clearly the repo is working when you create a fresh application.

those of you who are having this issue, are you using the promise library 'bluebird' by any chance?

Also having this issue, but not using bluebird, and only a very basic test script. I've tried explicitly setting, and omitting, the input parameter type.

please help... blocking problem
example...

const log = console;
const dbConfig = {
    "database": "..."
    , "user": "..."
    , "password": "..."
    , "server": "..."
    , "port": 1433
    , "pool": { "max": 50, "min": 0, "idleTimeoutMillis": 3000 }
    , "requestTimeout": 30000
};
const wtf = false;
if (wtf)
{
    Object.prototype.keyList = function () { return Object.keys(this); };
    log.info(dbConfig.keyList());
}
else log.info(Object.keys(dbConfig));
const db = require('mssql');
new db['ConnectionPool'](dbConfig)
    .connect()
    .then(pool => {
        pool.request().query('SELECT @@VERSION version', (err, res) => {
            if (err)
            {
                log.error('DB QUERY ERROR: %s', err.message);
                setTimeout(() => process.exit(102), 100);
                return;
            }
            log.info(res['recordset'][0]['version']);
        })
    })
    .catch(err => {
        log.error('DB POOL ERROR: %s', err.message);
    });

with wtf = false it;s working. set wtf = true and bye-bye logic
DB QUERY ERROR: Cannot read property 'validate' of undefined

I also can reproduce this error when including adding a function to Object.prototype. The cause is mssql's tedious.js, which does not check "hasOwnProperty" when looping through the names in this.parameters. Because the Object.prototype.[function] exists on this, an invalid output parameter is added. See example of problem code below:

for (let name in this.parameters) {
  let param = this.parameters[name]
  if (param.io === 1) {
    req.addParameter(param.name, getTediousType(param.type), parameterCorrection(param.value), {length: param.length, scale: param.scale, precision: param.precision})
  } else {
    req.addOutputParameter(param.name, getTediousType(param.type), parameterCorrection(param.value), {length: param.length, scale: param.scale, precision: param.precision})
  }
}

I'm not able to reproduce the issue. The error you get is because of invalid type of an input parameter. It's happening on this line. But the request you're creating in your sample has no parameters. Are you sure you're getting this error with exactly this sample code?

This answer was the issue in my case.
My teammate was using TYPES.NvarChar instead of TYPES.NVarChar

BTW, the sample code link is no longer pointing to the right line of code.

We should guard against this. Reopening.

BTW, the sample code link is no longer pointing to the right line of code.

I've updated the link to point to the commit as of 30th Jan 2016 (馃槚) so it should be "right" again

This is an issue in the tedious driver, not in our lib. I've opened https://github.com/tediousjs/tedious/pull/874

Right, I was mistaken, as @erika9star has pointed out, this is in our code - fix at #879

Applying the changes from #879 into my project worked for me

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mhunting picture mhunting  路  6Comments

agilitehub picture agilitehub  路  4Comments

jeetendra-choudhary picture jeetendra-choudhary  路  3Comments

sizovilya picture sizovilya  路  3Comments

PhantomRay picture PhantomRay  路  4Comments