Yann Pellegrini
Yann Pellegrini

Reputation: 843

Get informative stack trace in node-pg

I am using node-pg with typescript.

I have a getPool utility from the doc https://node-postgres.com/features/pooling

export const getPool = (config?: PoolConfig) => {
  const pool = new Pool(config);
  pool.on('error', (err, client) => {
    console.error('Unexpected error on idle client', err);
    process.exit(-1);
  });
  return pool;
};

I use it like this in an async/await context

const pool = getPool();
await pool.query('my sql query here...');

When I have an invalid SQL query I get this kind of error:

error: null value in column "foo" violates not-null constraint

  at Parser.parseErrorMessage (node_modules/pg-protocol/src/parser.ts:357:11)
  at Parser.handlePacket (node_modules/pg-protocol/src/parser.ts:186:21)
  at Parser.parse (node_modules/pg-protocol/src/parser.ts:101:30)
  at Socket.<anonymous> (node_modules/pg-protocol/src/index.ts:7:48)

Note: I would understand if it was the pool.on('error')'s callback that stole my stack trace, but the errors are not prefixed with Unexpected error on idle client

Notice in the stack trace there is no line that points to a file in my codebase.

My problem is, I have hundereds of queries in my codebase, and I would like to be able to trace the line that called the failing pool.query(). This would help a lot to find which query triggered the error.

Expected :

error: null value in column "foo" violates not-null constraint

  at ...
  at mycodebase/src/myfile.ts:42

Upvotes: 6

Views: 1078

Answers (2)

Benjamin Bohec
Benjamin Bohec

Reputation: 203

A recent update on node-postgres provides accurate stacktrace.

https://github.com/brianc/node-postgres/pull/2983

Upvotes: 1

MiF
MiF

Reputation: 678

I use dirty hack (patch Pool.prototype), but it works for me:

const originalPoolQuery = Pool.prototype.query;
Pool.prototype.query = async function query(...args) {
    try {
        return await originalPoolQuery.apply(this, args);
    } catch (e) {
        // All magic is here. new Error will generate new stack, but message will copyid from e
        throw new Error(e)
    }
}

// After hack create pool and good luck
const pool = new Pool({})

await pool.query('SELECT * FROM ...')

Stacktrace in this case will be more informative.

I think that pool.on('error', cb) is not for catching query errors, it for connection errors (i am not sure)

Upvotes: 1

Related Questions