node-postgres: TypeError: Cannot read property 'name' of null

First off, thanks for the library! Overall it’s been incredibly performant and straightforward to use. I am running into one issue which may be an issue with the library, though it’s a bit hard to follow the protocol for me so my usage may be off as well.

I’m running into an uncaught error during the parseComplete handler in client.js (https://github.com/brianc/node-postgres/blob/v6.0.1/lib/client.js#L131).

I am doing a direct connect against the pool and then utilizing pg-query-stream

pool.connect().then(function(client){
  stream = client.query(new QueryStream(query, null));

  stream.on('error', function(streamError){
    stream.close(function(closeError){ 
      // What to do with a close error? At this point stream is already hosed :shrug:
      client.release(streamError);
    }
  });

  stream.on('close', function(){
    client.release();
  }); 
});

At some point during my app’s life cycle, I get an uncaught error

TypeError: Cannot read property 'name' of null
    at null.<anonymous> (/var/app/current/node_modules/pg/lib/client.js:139:26)
    at emit (events.js:107:17)
    at Socket.<anonymous> (/var/app/current/node_modules/pg/lib/connection.js:121:12)
    at Socket.emit (events.js:107:17)
    at readableAddChunk (_stream_readable.js:163:16)
    at Socket.Readable.push (_stream_readable.js:126:10)
    at TCP.onread (net.js:540:20)

So obviously activeQuery is becoming null, and I am trying to narrow down why I would receive a parseComplete event when the active query is null.

According to my logs, the stream is not emitting an error, and seems to be closing normally. Therefore it seems like the connection client is getting a readyForQuery or end event, and then right after that getting the parseComplete event. Any idea why this would be happening, or see any issues with my usage? Thanks for any help you can give! I’ll keep looking into it as well.

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Comments: 65 (18 by maintainers)

Commits related to this issue

Most upvoted comments

Started getting this error after using the query_timeout config parameter, pg 7.10.0

Repro steps for me, using this config: { query_timeout: 10 * 1000, max: 32, min: 8 }

Steps: lock a table in the database and then issue queries against that table, so that they all time out; doesn’t have to be very fast, 1-2 per second will do. I get the crash very quickly, somewhere after around 10 to 100 query timeouts.

Other timing information, if it’s relevant: the database and node-postgres servers are on separate machines but the ping rtt is very low, 0.5 - 1ms.

I’m also using query_timeout:

[2019-07-11 09:36:36] [ERROR] [pid:8718] TypeError: Cannot read property ‘name’ of null TypeError: Cannot read property ‘name’ of null at Connection.<anonymous> (/opt/acn/4be1e1fb/api/node_modules/pg/lib/client.js:313:26) at emitOne (events.js:116:13) at Connection.emit (events.js:211:7) at Socket.<anonymous> (/opt/acn/4be1e1fb/api/node_modules/pg/lib/connection.js:126:12) at emitOne (events.js:116:13) at Socket.emit (events.js:211:7) at addChunk (_stream_readable.js:263:12) at readableAddChunk (_stream_readable.js:250:11) at Socket.Readable.push (_stream_readable.js:208:10) at TCP.onread (net.js:597:20)

@brianc Since I am not able to reproduce this using a script, and my production app is crashing because of this. I came up with a band-aid approach to stop production from crashing while more investigation is done into the root cause.

In my fork, I have a change (similar changes for all other places where this issue is happening)

  con.on('parseComplete', function (msg) {
    if (!self.activeQuery) {
      self.emit('invalidActiveQuery');
    } else if (self.activeQuery.name) {
      con.parsedStatements[self.activeQuery.name] = true
    }
  })

Here , I am emitting a invalidActiveQuery event. In my application, I listen for this event and if fired, I do the following:

  1. Drain the pool by calling end
  2. Re-create the pool

Do you see any potential issues with this approach ? Again I am not suggesting that this is the solution to this problem , it’s just a work-around.

quick question , from the comments in the code, it seems parseComplete is fired for prepared statements , is this assumption correct ?

Yah - any query w/ parameters has a parse phase which the backend returns a parseComplete on.

Also, what do you think about checking if activeQuery is null in commandComplete and parseComplete , do you see any issues with that ; I know you had some reservations about this based on the comment in #961

I feel like that’s similar to doing a try { something() } catch(e) { /* no big deal */ } and papers over what is a larger issue. I’d strongly prefer to have a reproducible test case & fix the underlying issue. Otherwise we’re hiding an error and as far as the protocol operation is concerned possibly putting the connection into a bad/unknown state.

My application (very rarely) has experienced this problem as well. We have unfortunately been unable to distill it down to a simple script/app that can reliably reproduce, but general observation so far seems to indicate this happens when there is a connection issue with the database.

@brianc : I can completely understand the need to be able to reproduce in order to fix - but what are your thoughts on a short term fix to at least check to make sure activeQuery is a valid object before trying to reference the name property? Given the inability for client applications to handle this error in any way… and its drastic consequences - would be great if some form of incremental improvement could be delivered…

https://github.com/brianc/node-postgres/blob/master/lib/client.js#L241 indicates access to the name attribute allows to avoid the client from re-parsing the query. I would much rather take extraneous reparsing when the alternative is uncaught exception 😇