From b693a113626a1b3f978c22e63e72ca1e9d439d0b Mon Sep 17 00:00:00 2001 From: Nigro Simone Date: Sun, 13 Sep 2026 12:23:56 +0200 Subject: [PATCH] fix(pg): expose detail and hint on errors from the native client --- packages/pg/lib/native/query.js | 2 + .../test/native/native-vs-js-error-tests.js | 41 +++++++++++++++---- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/packages/pg/lib/native/query.js b/packages/pg/lib/native/query.js index 8cb561979..2987abb91 100644 --- a/packages/pg/lib/native/query.js +++ b/packages/pg/lib/native/query.js @@ -35,6 +35,8 @@ const errorFieldMap = { sqlState: 'code', statementPosition: 'position', messagePrimary: 'message', + messageDetail: 'detail', + messageHint: 'hint', context: 'where', schemaName: 'schema', tableName: 'table', diff --git a/packages/pg/test/native/native-vs-js-error-tests.js b/packages/pg/test/native/native-vs-js-error-tests.js index d61b0c69d..b594e1708 100644 --- a/packages/pg/test/native/native-vs-js-error-tests.js +++ b/packages/pg/test/native/native-vs-js-error-tests.js @@ -6,16 +6,41 @@ const NativeClient = require('../../lib/native') const client = new Client() const nativeClient = new NativeClient() +// every field of an error the native client reports must be on the javascript one under the +// same name, and with the same value +const compare = (err, nativeErr) => { + for (const key in nativeErr) { + assert.equal(err[key], nativeErr[key], `Expected err.${key} to equal nativeErr.${key}`) + } +} + +const bothFail = (text, cb) => { + client.query(text, (err) => { + nativeClient.query(text, (nativeErr) => { + compare(err, nativeErr) + cb() + }) + }) +} + client.connect() nativeClient.connect((err) => { - client.query('SELECT alsdkfj', (err) => { - client.end() - - nativeClient.query('SELECT lkdasjfasd', (nativeErr) => { - for (const key in nativeErr) { - assert.equal(err[key], nativeErr[key], `Expected err.${key} to equal nativeErr.${key}`) - } - nativeClient.end() + assert(!err) + bothFail('SELECT alsdkfj', () => { + // a duplicate key carries a detail, a misspelt column a hint. A real table rather than a + // temp one, whose schema is named after the connection + const setup = + 'DROP TABLE IF EXISTS native_vs_js_dup; CREATE TABLE native_vs_js_dup (id int PRIMARY KEY); INSERT INTO native_vs_js_dup VALUES (1)' + client.query(setup, (err) => { + assert(!err) + bothFail('INSERT INTO native_vs_js_dup VALUES (1)', () => { + bothFail('SELECT cols FROM (SELECT 1 AS col) t', () => { + client.query('DROP TABLE native_vs_js_dup', () => { + client.end() + nativeClient.end() + }) + }) + }) }) }) })