Hi there, thanks for maintaining this the postgres library, it's quite nice.
I wonder if error messages could give more context.
Let's step into the Postgres console with the provided schema
CREATE DATABASE people;
\c people
CREATE TABLE person (
id BIGSERIAL PRIMARY KEY,
name TEXT,
age INTEGER
);
If I run the invalid query
INSERT INTO person(name, age) VALUES('Eric', 'thirty-one') RETURNING *;
Postgres tells me not just the error, but points to the place in my code where the error came from
ERROR: invalid input syntax for integer: "thirty-one"
LINE 1: INSERT INTO person(name, age) VALUES('Eric', 'thirty-one') R...
^
This is useful, because I notice I provided 'thirty-one' where an integer was expected.
I run the same INSERT INTO statement with node-postgres with this code
// pg-test.js
const { Pool, Client } = require("pg");
const client = new Client();
const main = async () => {
await client.connect();
const text = "INSERT INTO person(name, age) VALUES($1, $2) RETURNING *";
const values = ["Eric", "thirty-one"];
client.query(text, values, (err, res) => {
console.log(err ? err.stack : res.rows[0]);
client.end();
});
};
main();
and get a different error stack
error: invalid input syntax for integer: "thirty-one"
at Connection.parseE (/Users/ericlewis/Desktop/jjj/node_modules/pg/lib/connection.js:545:11)
at Connection.parseMessage (/Users/ericlewis/Desktop/jjj/node_modules/pg/lib/connection.js:370:19)
at Socket.<anonymous> (/Users/ericlewis/Desktop/jjj/node_modules/pg/lib/connection.js:113:22)
at Socket.emit (events.js:180:13)
at addChunk (_stream_readable.js:269:12)
at readableAddChunk (_stream_readable.js:256:11)
at Socket.Readable.push (_stream_readable.js:213:10)
at TCP.onread (net.js:581:20)
I assume it might be possible to configure node-postgres to output long stack traces as pg-promise can which might inform you what line of your code the problem started from.
To think about the problem from a higher level, I wonder what error we would want to see as developers here.
Something like this might be nice:
Error in Postgres query:
INSERT INTO person(name, age) VALUES('Eric', 'thirty-one')
age column is of type INTEGER, TEXT provided ('thirty-one')
Invoked at pg-test.js, line 11:
client.query(text, values, (err, res) => {
// maybe huge stack trace here
I don't have any particular recommendation here, just want to ask: do you think there are ways to improve the error messages?
As of this day, Long Stack Tracing still remains the feature that properly works only in Bluebird.
For the default Promise you can only try some hacks, like long-promise, which I never tested, so I don't know if it even works.
That would be nice to have at least name of invalid argument so as a developer I can investigate which exact field is incorrect. In my case, I have an INSERT query with more then 100 column names passed, and one argument value is incorrect (different type or something) and can not understant which one exactly cause the problem!
That is how my error message looks like for more than 100 args passed to INSERT query:
info: error: invalid input syntax for type boolean: ""
Which one?? Which line?? Damn!
@romangromov If you look at the rest of the properties of the error object, all the information PostgreSQL provides to pg should be present.
I think the feature request here is to put those into the stack property as well?
As of this day, Long Stack Tracing still remains the feature that properly works only in Bluebird.
Whats the reason node-postgres does not allow to override Promise implementation, just like pg-promise?
It turned out it is easy to solve this issue by simply wrapping the query promise, e.g. https://github.com/gajus/slonik/commit/9856d4524ec45a73eb6bf2ff4f6a54390288da7d.
On a second thought, considering that this is used only for debugging, it is even more convenient to log the stack trace for every query _before_ the query was executed, e.g.
https://github.com/gajus/slonik/commit/81312c5b6303131ebff26de4ac63bf82bb995244
Huge +1 to this, and while I'm at it stack traces are completely lost because the module throws itself instead of rejecting the promise. This is a HUGE annoyance because it goes from being able to effortlessly find the exact line of code at the top of the stack trace that caused the error I have to repro it, then go through every single query (which can sometimes be hundreds of lines of code) until I find the offender.
If you simply want to locate the invalid statement for debugging, you could just print a stack trace within your handler function.
client.query(text, values, (err, res) => {
if (err) {
console.trace();
console.log(err);
} else {
console.log(res.rows[0]);
}
client.end();
});
Most helpful comment
Huge +1 to this, and while I'm at it stack traces are completely lost because the module throws itself instead of rejecting the promise. This is a HUGE annoyance because it goes from being able to effortlessly find the exact line of code at the top of the stack trace that caused the error I have to repro it, then go through every single query (which can sometimes be hundreds of lines of code) until I find the offender.