@@ -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