Skip to content

Commit 21d100f

Browse files
committed
fix: use bind and catch unexpected error
1 parent 02fd305 commit 21d100f

File tree

1 file changed

+82
-79
lines changed

1 file changed

+82
-79
lines changed

src/lib/db.ts

+82-79
Original file line numberDiff line numberDiff line change
@@ -99,111 +99,114 @@ export const init: (config: PoolConfig) => {
9999
return {
100100
async query(sql) {
101101
try {
102-
if (!pool) {
103-
const pool = new pg.Pool(config)
102+
try {
103+
if (!pool) {
104+
const pool = new pg.Pool(config)
105+
let res = await poolerQueryHandleError(pool, sql)
106+
if (Array.isArray(res)) {
107+
res = res.reverse().find((x) => x.rows.length !== 0) ?? { rows: [] }
108+
}
109+
await pool.end()
110+
return { data: res.rows, error: null }
111+
}
112+
104113
let res = await poolerQueryHandleError(pool, sql)
105114
if (Array.isArray(res)) {
106115
res = res.reverse().find((x) => x.rows.length !== 0) ?? { rows: [] }
107116
}
108-
await pool.end()
109117
return { data: res.rows, error: null }
110-
}
111-
112-
let res = await poolerQueryHandleError(pool, sql)
113-
if (Array.isArray(res)) {
114-
res = res.reverse().find((x) => x.rows.length !== 0) ?? { rows: [] }
115-
}
116-
return { data: res.rows, error: null }
117-
} catch (error: any) {
118-
if (error.constructor.name === 'DatabaseError') {
119-
// Roughly based on:
120-
// - https://github.com/postgres/postgres/blob/fc4089f3c65a5f1b413a3299ba02b66a8e5e37d0/src/interfaces/libpq/fe-protocol3.c#L1018
121-
// - https://github.com/brianc/node-postgres/blob/b1a8947738ce0af004cb926f79829bb2abc64aa6/packages/pg/lib/native/query.js#L33
122-
let formattedError = ''
123-
{
124-
if (error.severity) {
125-
formattedError += `${error.severity}: `
126-
}
127-
if (error.code) {
128-
formattedError += `${error.code}: `
129-
}
130-
if (error.message) {
131-
formattedError += error.message
132-
}
133-
formattedError += '\n'
134-
if (error.position) {
135-
// error.position is 1-based
136-
const position = Number(error.position) - 1
118+
} catch (error: any) {
119+
if (error.constructor.name === 'DatabaseError') {
120+
// Roughly based on:
121+
// - https://github.com/postgres/postgres/blob/fc4089f3c65a5f1b413a3299ba02b66a8e5e37d0/src/interfaces/libpq/fe-protocol3.c#L1018
122+
// - https://github.com/brianc/node-postgres/blob/b1a8947738ce0af004cb926f79829bb2abc64aa6/packages/pg/lib/native/query.js#L33
123+
let formattedError = ''
124+
{
125+
if (error.severity) {
126+
formattedError += `${error.severity}: `
127+
}
128+
if (error.code) {
129+
formattedError += `${error.code}: `
130+
}
131+
if (error.message) {
132+
formattedError += error.message
133+
}
134+
formattedError += '\n'
135+
if (error.position) {
136+
// error.position is 1-based
137+
const position = Number(error.position) - 1
137138

138-
let line = ''
139-
let lineNumber = 0
140-
let lineOffset = 0
139+
let line = ''
140+
let lineNumber = 0
141+
let lineOffset = 0
141142

142-
const lines = sql.split('\n')
143-
let currentOffset = 0
144-
for (let i = 0; i < lines.length; i++) {
145-
if (currentOffset + lines[i].length > position) {
146-
line = lines[i]
147-
lineNumber = i + 1 // 1-based
148-
lineOffset = position - currentOffset
149-
break
143+
const lines = sql.split('\n')
144+
let currentOffset = 0
145+
for (let i = 0; i < lines.length; i++) {
146+
if (currentOffset + lines[i].length > position) {
147+
line = lines[i]
148+
lineNumber = i + 1 // 1-based
149+
lineOffset = position - currentOffset
150+
break
151+
}
152+
currentOffset += lines[i].length + 1 // 1 extra offset for newline
150153
}
151-
currentOffset += lines[i].length + 1 // 1 extra offset for newline
152-
}
153-
formattedError += `LINE ${lineNumber}: ${line}
154+
formattedError += `LINE ${lineNumber}: ${line}
154155
${' '.repeat(5 + lineNumber.toString().length + 2 + lineOffset)}^
155156
`
156-
}
157-
if (error.detail) {
158-
formattedError += `DETAIL: ${error.detail}
157+
}
158+
if (error.detail) {
159+
formattedError += `DETAIL: ${error.detail}
159160
`
160-
}
161-
if (error.hint) {
162-
formattedError += `HINT: ${error.hint}
161+
}
162+
if (error.hint) {
163+
formattedError += `HINT: ${error.hint}
163164
`
164-
}
165-
if (error.internalQuery) {
166-
formattedError += `QUERY: ${error.internalQuery}
165+
}
166+
if (error.internalQuery) {
167+
formattedError += `QUERY: ${error.internalQuery}
167168
`
168-
}
169-
if (error.where) {
170-
formattedError += `CONTEXT: ${error.where}
169+
}
170+
if (error.where) {
171+
formattedError += `CONTEXT: ${error.where}
171172
`
173+
}
172174
}
173-
}
174175

175-
return {
176-
data: null,
177-
error: {
178-
...error,
179-
// error.message is non-enumerable
180-
message: error.message,
181-
formattedError,
182-
},
183-
}
184-
}
185-
try {
186-
// Handle stream errors and result size exceeded errors
187-
if (error.code === 'RESULT_SIZE_EXCEEDED') {
188-
// Force kill the connection without waiting for graceful shutdown
189176
return {
190177
data: null,
191178
error: {
192-
message: `Query result size (${error.resultSize} bytes) exceeded the configured limit (${error.maxResultSize} bytes)`,
193-
code: error.code,
194-
resultSize: error.resultSize,
195-
maxResultSize: error.maxResultSize,
179+
...error,
180+
// error.message is non-enumerable
181+
message: error.message,
182+
formattedError,
196183
},
197184
}
198185
}
199-
return { data: null, error: { code: error.code, message: error.message } }
200-
} finally {
201-
if (this && this.end) {
186+
try {
187+
// Handle stream errors and result size exceeded errors
188+
if (error.code === 'RESULT_SIZE_EXCEEDED') {
189+
// Force kill the connection without waiting for graceful shutdown
190+
return {
191+
data: null,
192+
error: {
193+
message: `Query result size (${error.resultSize} bytes) exceeded the configured limit (${error.maxResultSize} bytes)`,
194+
code: error.code,
195+
resultSize: error.resultSize,
196+
maxResultSize: error.maxResultSize,
197+
},
198+
}
199+
}
200+
return { data: null, error: { code: error.code, message: error.message } }
201+
} finally {
202202
// If the error isn't a "DatabaseError" assume it's a connection related we kill the connection
203203
// To attempt a clean reconnect on next try
204-
await this.end()
204+
await this.end.bind(this)
205205
}
206206
}
207+
} catch (error) {
208+
// In case the connection cannot be gracefully ended log the error
209+
console.error('Failed to end the connection on error: ', { this: this, end: this.end })
207210
}
208211
},
209212

0 commit comments

Comments
 (0)