Skip to content

Commit

Permalink
Add PostgresError type
Browse files Browse the repository at this point in the history
  • Loading branch information
porsager committed Apr 7, 2020
1 parent 4958e80 commit fc6804a
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 35 deletions.
7 changes: 4 additions & 3 deletions lib/backend.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const { errorFields, errors, entries } = require('./types.js')
const { errors } = require('./errors.js')
, { entries, errorFields } = require('./types.js')

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

function ErrorResponse(x) {
backend.query
? (backend.error = errors.generic(parseError(x)))
: error(errors.generic(parseError(x)))
? (backend.error = errors.postgres(parseError(x)))
: error(errors.postgres(parseError(x)))
}

/* c8 ignore next 3 */
Expand Down
7 changes: 4 additions & 3 deletions lib/connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ const tls = require('tls')
const frontend = require('./frontend.js')
const Backend = require('./backend.js')
const Queue = require('./queue.js')
const { errors, END } = require('./types.js')
const { END } = require('./types.js')
const { errors } = require('./errors.js')

module.exports = Connection

Expand Down Expand Up @@ -99,7 +100,7 @@ function Connection(options = {}) {
}

function destroy() {
error(errors.connection('DESTROYED', options))
error(errors.connection('CONNECTION_DESTROYED', options))
socket.destroy()
}

Expand Down Expand Up @@ -224,7 +225,7 @@ function Connection(options = {}) {

function close() {
connect_timer && (clearTimeout(connect_timer), connect_timer = null)
error(errors.connection('CLOSED', options))
error(errors.connection('CONNECTION_CLOSED', options))
statements = {}
messages = []
open = ready = false
Expand Down
53 changes: 53 additions & 0 deletions lib/errors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
class PostgresError extends Error {
constructor(x) {
super(x.message)
this.name = this.constructor.name
Object.assign(this, x)
}
}

module.exports.PostgresError = PostgresError

module.exports.errors = {
connection,
postgres,
generic,
notSupported
}

function connection(x, options) {
const error = Object.assign(
new Error(('write ' + x + ' ' + (options.path || (options.host + ':' + options.port)))),
{
code: x,
errno: x,
address: options.path || options.host
}, options.path ? {} : { port: options.port }
)
Error.captureStackTrace(error, connection)
return error
}

function postgres(x) {
const error = new PostgresError(x)
Error.captureStackTrace(error, postgres)
return error
}

function generic(x) {
const error = Object.assign(new Error(x.message), x)
Error.captureStackTrace(error, generic)
return error
}

function notSupported(x) {
const error = Object.assign(
new Error(x + ' (B) is not supported'),
{
code: 'MESSAGE_NOT_SUPPORTED',
name: x
}
)
Error.captureStackTrace(error, notSupported)
return error
}
3 changes: 2 additions & 1 deletion lib/frontend.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const crypto = require('crypto')
const bytes = require('./bytes.js')
const { errors, entries } = require('./types.js')
const { entries } = require('./types.js')
const { errors } = require('./errors.js')

const N = String.fromCharCode(0)
const empty = Buffer.alloc(0)
Expand Down
5 changes: 3 additions & 2 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const fs = require('fs')
const Url = require('url')
const Connection = require('./connection.js')
const Queue = require('./queue.js')
const { errors, PostgresError } = require('./errors.js')
const {
mergeUserTypes,
arraySerializer,
Expand All @@ -11,7 +12,6 @@ const {
entries,
toCamel,
toKebab,
errors,
escape,
types,
END
Expand Down Expand Up @@ -174,7 +174,7 @@ function Postgres(a, b) {
query.resolve = resolve
query.reject = reject
ended !== null
? reject(errors.connection('ENDED', options))
? reject(errors.connection('CONNECTION_ENDED', options))
: ready
? send(connection, query, xs, args)
: fetchArrayTypes(connection).then(() => send(connection, query, xs, args)).catch(reject)
Expand Down Expand Up @@ -270,6 +270,7 @@ function Postgres(a, b) {
function addTypes(sql, connection) {
Object.assign(sql, {
END,
PostgresError,
types: {},
notify,
unsafe,
Expand Down
25 changes: 1 addition & 24 deletions lib/types.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const char = (acc, [k, v]) => (acc[k.charCodeAt(0)] = v, acc)
const char = module.exports.char = (acc, [k, v]) => (acc[k.charCodeAt(0)] = v, acc)
const entries = o => Object.keys(o).map(x => [x, o[x]])

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

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

module.exports.errors = {
connection: (x, options) => Object.assign(
new Error(('write CONNECTION_' + x + ' ' + (options.path || (options.host + ':' + options.port)))),
{
code: 'CONNECTION_' + x,
errno: 'CONNECTION_' + x,
address: options.path || options.host
}, options.path ? {} : { port: options.port }
),

generic: (x) => Object.assign(
new Error(x.message),
x
),

notSupported: x => Object.assign(
new Error(x + ' (B) is not supported'),
{
code: 'MESSAGE_NOT_SUPPORTED'
}
)
}

module.exports.errorFields = entries({
S: 'severity_local',
V: 'severity',
Expand Down
8 changes: 6 additions & 2 deletions tests/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -935,7 +935,7 @@ t('Query parameters are not enumerable', async() => [
])

t('connect_timeout throws proper error', async() => [
'CONNECTION_CONNECT_TIMEOUT',
'CONNECT_TIMEOUT',
await postgres({
...options,
...login_scram,
Expand All @@ -953,11 +953,15 @@ t('requests works after single connect_timeout', async() => {
})

return [
'CONNECTION_CONNECT_TIMEOUT,,1',
'CONNECT_TIMEOUT,,1',
[
await sql`select 1 as x`.catch(x => x.code),
await new Promise(r => setTimeout(r, 10)),
(await sql`select 1 as x`)[0].x
].join(',')
]
})

t('Postgres errors are of type PostgresError', async() =>
[true, (await sql`bad keyword`.catch(e => e)) instanceof sql.PostgresError]
)

0 comments on commit fc6804a

Please sign in to comment.