6

I'm having an issue catching an error thrown from the Node-Postgres NPM package.

The issue seems simple on the surface, but I've tried everything I can think of.

My code is like the following:

import { Pool } from 'pg' // Import postgres connection pool
const pgPool = new Pool()

async function queryDatabase() {
  try {

    // Force TypeError by passing undefined
    let queryResult = await pgPool.query( undefined )

    if ( queryResult.rows.length > 0 ) {
      return queryResult.rows[0]
    }

    return false

  } catch( err ) {

    // Never Reached
    return new Error( 'Test error' )

  }
}
queryDatabase()

And the error is as follows:

TypeError: Client was passed a null or undefined query
at Client.query (~/.../node_modules/pg/lib/client.js:479:11)

The error itself is pretty self-explanatory. I'm forcing the error here, for the sake of trying to handle it in the event that undefined gets passed by mistake. I realize that I can simply perform a check to make sure the input is never null or undefined, but that's not my main concern.

My worry is if I can't catch this error thrown from this package, how many other unforeseen cases am I going to encounter where I simply can't catch and handle a thrown error.

I've tried numerous different approaches - The Async/Await Try/Catch method, shown above - I've tried pgPool.query().then().catch() - Combinations of the two. I've even tried running the catch against the Pool instance itself. No matter what I do, I can't handle the exception without using Node's process.on('unhandledRejection', ...), which is of course a bad idea.

I've been racking my brain on this for hours. Is there any way that I can catch and handle errors like this, so it's not crashing my server every time? Thanks in advance!

3
  • stackoverflow.com/questions/58831423/… Commented Dec 9, 2020 at 18:21
  • I appreciate the quick response, but that does not work. The pg package does not route this specific error through their error handler. They just throw it. Commented Dec 9, 2020 at 18:24
  • If passing undefined causes an exception that the above code does not catch, that's a bug. Please ensure you have the latest version of pg, then report the issue at github. Commented Dec 9, 2020 at 18:39

1 Answer 1

6

I was able to reproduce this and it seems to be an actual bug in the pg-library.

According to the source if you call .query on a pool instance, this instance will attempt to connect and get a client. In this connect-callback the actual query is dispatched to the client-module, which will throw the mentioned type error if the query is nil.

This error is thrown synchronously (i.e. the error is not passed to the callback argument, e.g. callback(new TypeError("...")) and since there's no try/catch around the client.query call in the pool's connect-callback, the error will not be caught by your try/catch.

A potential fix would be to wrap the client.query call in a try catch:

 client.once('error', onError)
      this.log('dispatching query')
      try {
        client.query(text, values, (err, res) => {
          this.log('query dispatched')
          client.removeListener('error', onError)
          if (clientReleased) {
            return
          }
          clientReleased = true
          client.release(err)
          if (err) {
            return cb(err)
          } else {
            return cb(undefined, res)
          }
        })
      }catch(err) {
        return cb(err)
      }

So for now, you probably should create an issue on github and wait for the bugfix or fork the repo and use above workaround, I'm afraid.

Sign up to request clarification or add additional context in comments.

1 Comment

I appreciate the response. It's unfortunate that it's an issue with the package. I suppose my confusion stemmed from not knowing that thrown errors wouldn't bubble up through the call stack. Seems rather inefficient.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.