@@ -99,111 +99,114 @@ export const init: (config: PoolConfig) => {
99
99
return {
100
100
async query ( sql ) {
101
101
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
+
104
113
let res = await poolerQueryHandleError ( pool , sql )
105
114
if ( Array . isArray ( res ) ) {
106
115
res = res . reverse ( ) . find ( ( x ) => x . rows . length !== 0 ) ?? { rows : [ ] }
107
116
}
108
- await pool . end ( )
109
117
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
137
138
138
- let line = ''
139
- let lineNumber = 0
140
- let lineOffset = 0
139
+ let line = ''
140
+ let lineNumber = 0
141
+ let lineOffset = 0
141
142
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
150
153
}
151
- currentOffset += lines [ i ] . length + 1 // 1 extra offset for newline
152
- }
153
- formattedError += `LINE ${ lineNumber } : ${ line }
154
+ formattedError += `LINE ${ lineNumber } : ${ line }
154
155
${ ' ' . repeat ( 5 + lineNumber . toString ( ) . length + 2 + lineOffset ) } ^
155
156
`
156
- }
157
- if ( error . detail ) {
158
- formattedError += `DETAIL: ${ error . detail }
157
+ }
158
+ if ( error . detail ) {
159
+ formattedError += `DETAIL: ${ error . detail }
159
160
`
160
- }
161
- if ( error . hint ) {
162
- formattedError += `HINT: ${ error . hint }
161
+ }
162
+ if ( error . hint ) {
163
+ formattedError += `HINT: ${ error . hint }
163
164
`
164
- }
165
- if ( error . internalQuery ) {
166
- formattedError += `QUERY: ${ error . internalQuery }
165
+ }
166
+ if ( error . internalQuery ) {
167
+ formattedError += `QUERY: ${ error . internalQuery }
167
168
`
168
- }
169
- if ( error . where ) {
170
- formattedError += `CONTEXT: ${ error . where }
169
+ }
170
+ if ( error . where ) {
171
+ formattedError += `CONTEXT: ${ error . where }
171
172
`
173
+ }
172
174
}
173
- }
174
175
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
189
176
return {
190
177
data : null ,
191
178
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 ,
196
183
} ,
197
184
}
198
185
}
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 {
202
202
// If the error isn't a "DatabaseError" assume it's a connection related we kill the connection
203
203
// To attempt a clean reconnect on next try
204
- await this . end ( )
204
+ await this . end . bind ( this )
205
205
}
206
206
}
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 } )
207
210
}
208
211
} ,
209
212
0 commit comments