Bug:
If a query_timeout is reached when using a submit-able query object that doesn't have a callback method on it (such as all streaming query types, and probably most user-crafted submit-ables), then the Client will throw a queryCallback is not a function error. General repro would be:
const pg = require('pg')
const QueryStream = require('pg-query-stream')
const db = new pg.Client({ ..., query_timeout: 1000 })
db.connect(err => {
if (err) throw new Error('Connection error')
const qs = new QueryStream('SELECT pg_sleep(2)')
db.query(qs)
.on('data', d => console.log('data', d))
.on('end', d => console.log('end', d))
.on('error', d => (qs.close(), console.log('error', d)))
})
Analysis:
Although the node-postgres Query object has a callback method for handling bulk results, other streaming objects, such as pg-cursor and pg-query-stream, do not have such a method. Looking at the code in client.js, we see: https://github.com/brianc/node-postgres/blob/master/lib/client.js#L431-L457
If the Query object has a submit method on it, and no callback method, and if no callback is passed in as the second (values) argument to Client#query, then query.callback will be undefined. Subsequently if a readTimeout is specified (either as a query_timeout on the Query object, or as part of the database configuration), then the read timeout assumes that query.callback is defined and attempts to call it, resulting in a TypeError: queryCallback is not a function.
Fix:
Since the callback attribute appears to be an implementation detail of the node-postgres Query object, and the documentation for Client#query does not indicate that this method should be present, or that a second parameter should be passed, it's unclear whether the fix is to make callback a required attribute on all Query-like objects, or if it's to fail gracefully if such a callback does not exist.
Furthermore, it's debatable whether a query_timeout is even appropriate on non-bulk query types (timeout to results ready? timeout until entire result set has been retrieved?), and whether that timeout code should move into the typical bulk Query object itself, dodging the issue entirely.
Because that's unclear, I'm leaving it to you to decide. Happy to submit a pull-request with a fix if you can tell me where/what you think the appropriate fix is.
Bug:
If a
query_timeoutis reached when using asubmit-able query object that doesn't have acallbackmethod on it (such as all streaming query types, and probably most user-craftedsubmit-ables), then the Client will throw aqueryCallback is not a functionerror. General repro would be:Analysis:
Although the
node-postgresQueryobject has acallbackmethod for handling bulk results, other streaming objects, such aspg-cursorandpg-query-stream, do not have such a method. Looking at the code inclient.js, we see: https://github.com/brianc/node-postgres/blob/master/lib/client.js#L431-L457If the Query object has a
submitmethod on it, and nocallbackmethod, and if no callback is passed in as the second (values) argument toClient#query, thenquery.callbackwill be undefined. Subsequently if areadTimeoutis specified (either as aquery_timeouton the Query object, or as part of the database configuration), then the read timeout assumes thatquery.callbackis defined and attempts to call it, resulting in aTypeError: queryCallback is not a function.Fix:
Since the
callbackattribute appears to be an implementation detail of thenode-postgresQueryobject, and the documentation forClient#querydoes not indicate that this method should be present, or that a second parameter should be passed, it's unclear whether the fix is to makecallbacka required attribute on allQuery-like objects, or if it's to fail gracefully if such a callback does not exist.Furthermore, it's debatable whether a
query_timeoutis even appropriate on non-bulk query types (timeout to results ready? timeout until entire result set has been retrieved?), and whether that timeout code should move into the typical bulkQueryobject itself, dodging the issue entirely.Because that's unclear, I'm leaving it to you to decide. Happy to submit a pull-request with a fix if you can tell me where/what you think the appropriate fix is.