Skip to content

Commit fc6804a

Browse files
committed
Add PostgresError type
1 parent 4958e80 commit fc6804a

File tree

7 files changed

+73
-35
lines changed

7 files changed

+73
-35
lines changed

lib/backend.js

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
const { errorFields, errors, entries } = require('./types.js')
1+
const { errors } = require('./errors.js')
2+
, { entries, errorFields } = require('./types.js')
23

34
const char = (acc, [k, v]) => (acc[k.charCodeAt(0)] = v, acc)
45
, N = '\u0000'
@@ -125,8 +126,8 @@ function Backend({
125126

126127
function ErrorResponse(x) {
127128
backend.query
128-
? (backend.error = errors.generic(parseError(x)))
129-
: error(errors.generic(parseError(x)))
129+
? (backend.error = errors.postgres(parseError(x)))
130+
: error(errors.postgres(parseError(x)))
130131
}
131132

132133
/* c8 ignore next 3 */

lib/connection.js

+4-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ const tls = require('tls')
33
const frontend = require('./frontend.js')
44
const Backend = require('./backend.js')
55
const Queue = require('./queue.js')
6-
const { errors, END } = require('./types.js')
6+
const { END } = require('./types.js')
7+
const { errors } = require('./errors.js')
78

89
module.exports = Connection
910

@@ -99,7 +100,7 @@ function Connection(options = {}) {
99100
}
100101

101102
function destroy() {
102-
error(errors.connection('DESTROYED', options))
103+
error(errors.connection('CONNECTION_DESTROYED', options))
103104
socket.destroy()
104105
}
105106

@@ -224,7 +225,7 @@ function Connection(options = {}) {
224225

225226
function close() {
226227
connect_timer && (clearTimeout(connect_timer), connect_timer = null)
227-
error(errors.connection('CLOSED', options))
228+
error(errors.connection('CONNECTION_CLOSED', options))
228229
statements = {}
229230
messages = []
230231
open = ready = false

lib/errors.js

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
class PostgresError extends Error {
2+
constructor(x) {
3+
super(x.message)
4+
this.name = this.constructor.name
5+
Object.assign(this, x)
6+
}
7+
}
8+
9+
module.exports.PostgresError = PostgresError
10+
11+
module.exports.errors = {
12+
connection,
13+
postgres,
14+
generic,
15+
notSupported
16+
}
17+
18+
function connection(x, options) {
19+
const error = Object.assign(
20+
new Error(('write ' + x + ' ' + (options.path || (options.host + ':' + options.port)))),
21+
{
22+
code: x,
23+
errno: x,
24+
address: options.path || options.host
25+
}, options.path ? {} : { port: options.port }
26+
)
27+
Error.captureStackTrace(error, connection)
28+
return error
29+
}
30+
31+
function postgres(x) {
32+
const error = new PostgresError(x)
33+
Error.captureStackTrace(error, postgres)
34+
return error
35+
}
36+
37+
function generic(x) {
38+
const error = Object.assign(new Error(x.message), x)
39+
Error.captureStackTrace(error, generic)
40+
return error
41+
}
42+
43+
function notSupported(x) {
44+
const error = Object.assign(
45+
new Error(x + ' (B) is not supported'),
46+
{
47+
code: 'MESSAGE_NOT_SUPPORTED',
48+
name: x
49+
}
50+
)
51+
Error.captureStackTrace(error, notSupported)
52+
return error
53+
}

lib/frontend.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
const crypto = require('crypto')
22
const bytes = require('./bytes.js')
3-
const { errors, entries } = require('./types.js')
3+
const { entries } = require('./types.js')
4+
const { errors } = require('./errors.js')
45

56
const N = String.fromCharCode(0)
67
const empty = Buffer.alloc(0)

lib/index.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ const fs = require('fs')
22
const Url = require('url')
33
const Connection = require('./connection.js')
44
const Queue = require('./queue.js')
5+
const { errors, PostgresError } = require('./errors.js')
56
const {
67
mergeUserTypes,
78
arraySerializer,
@@ -11,7 +12,6 @@ const {
1112
entries,
1213
toCamel,
1314
toKebab,
14-
errors,
1515
escape,
1616
types,
1717
END
@@ -174,7 +174,7 @@ function Postgres(a, b) {
174174
query.resolve = resolve
175175
query.reject = reject
176176
ended !== null
177-
? reject(errors.connection('ENDED', options))
177+
? reject(errors.connection('CONNECTION_ENDED', options))
178178
: ready
179179
? send(connection, query, xs, args)
180180
: fetchArrayTypes(connection).then(() => send(connection, query, xs, args)).catch(reject)
@@ -270,6 +270,7 @@ function Postgres(a, b) {
270270
function addTypes(sql, connection) {
271271
Object.assign(sql, {
272272
END,
273+
PostgresError,
273274
types: {},
274275
notify,
275276
unsafe,

lib/types.js

+1-24
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
const char = (acc, [k, v]) => (acc[k.charCodeAt(0)] = v, acc)
1+
const char = module.exports.char = (acc, [k, v]) => (acc[k.charCodeAt(0)] = v, acc)
22
const entries = o => Object.keys(o).map(x => [x, o[x]])
33

44
// These were the fastest ways to do it in Node.js v12.11.1 (add tests to revise if this changes)
@@ -189,29 +189,6 @@ module.exports.toPascal = x => {
189189

190190
module.exports.toKebab = x => x.replace(/_/g, '-')
191191

192-
module.exports.errors = {
193-
connection: (x, options) => Object.assign(
194-
new Error(('write CONNECTION_' + x + ' ' + (options.path || (options.host + ':' + options.port)))),
195-
{
196-
code: 'CONNECTION_' + x,
197-
errno: 'CONNECTION_' + x,
198-
address: options.path || options.host
199-
}, options.path ? {} : { port: options.port }
200-
),
201-
202-
generic: (x) => Object.assign(
203-
new Error(x.message),
204-
x
205-
),
206-
207-
notSupported: x => Object.assign(
208-
new Error(x + ' (B) is not supported'),
209-
{
210-
code: 'MESSAGE_NOT_SUPPORTED'
211-
}
212-
)
213-
}
214-
215192
module.exports.errorFields = entries({
216193
S: 'severity_local',
217194
V: 'severity',

tests/index.js

+6-2
Original file line numberDiff line numberDiff line change
@@ -935,7 +935,7 @@ t('Query parameters are not enumerable', async() => [
935935
])
936936

937937
t('connect_timeout throws proper error', async() => [
938-
'CONNECTION_CONNECT_TIMEOUT',
938+
'CONNECT_TIMEOUT',
939939
await postgres({
940940
...options,
941941
...login_scram,
@@ -953,11 +953,15 @@ t('requests works after single connect_timeout', async() => {
953953
})
954954

955955
return [
956-
'CONNECTION_CONNECT_TIMEOUT,,1',
956+
'CONNECT_TIMEOUT,,1',
957957
[
958958
await sql`select 1 as x`.catch(x => x.code),
959959
await new Promise(r => setTimeout(r, 10)),
960960
(await sql`select 1 as x`)[0].x
961961
].join(',')
962962
]
963963
})
964+
965+
t('Postgres errors are of type PostgresError', async() =>
966+
[true, (await sql`bad keyword`.catch(e => e)) instanceof sql.PostgresError]
967+
)

0 commit comments

Comments
 (0)