You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
pg-cursor type parser exceptions escape read error handling and crash Node #3839
Node 22.23.4, PostgreSQL 16.15, pg 8.23.1, pg-cursor 2.22.1, pg-query-stream 4.17.1. Reproduced against current master 2a5850f on Windows.
Problem
When a custom type parser throws while pg-cursor is reading rows, the exception escapes the PostgreSQL message handler. It does not reject the read promise or reach the read callback. A process can therefore terminate even though the application awaits the read inside try/catch. pg-query-stream inherits the same behavior.
The equivalent normal client.query({ text, types }) correctly rejects and leaves the client usable.
Minimal reproduction
Use the normal PGHOST/PGPORT/PGUSER/PGDATABASE configuration for a local PostgreSQL instance. Install pg and pg-cursor, then run:
const{ Client }=require('pg');constCursor=require('pg-cursor');asyncfunctionrun(){constclient=newClient();awaitclient.connect();try{consttypes={getTypeParser: ()=>value=>{if(value==='3')thrownewError('cannot decode value');returnNumber(value);}};constcursor=client.query(newCursor('SELECT value FROM generate_series(1, 6) value',[],{ types }));awaitcursor.read(20);}catch(error){console.log('caught:',error.message);console.log((awaitclient.query('SELECT 42 AS answer')).rows);}finally{awaitclient.end();}}run().catch(console.error);
Actual: uncaught Error: cannot decode value, through Result.parseRow and Cursor.handleDataRow; the inner catch is never entered and Node exits.
Expected: the read rejects with the parser error, the cursor portal is released, and the catch/finally execute. A subsequent normal query on the client should work.
Investigation
Cursor.handleDataRow() calls parseRow() without the error handling used by the core Query implementation. The correction must also respect protocol boundaries: retain the error, drain the current batch, close the portal, and report completion after ReadyForQuery. Reporting immediately without cleanup can leave the connection in an inconsistent state.
I found no matching parser-error fix in current code or targeted open/closed tracker searches. Related #3808/#3796/#3813 address timeout, close and concurrent-read behavior; #3825/#3712 address core query behavior, not this cursor parser path.
I have regression coverage for object/array rows, suspended/final batches, queued and subsequent reads, callback/promise/stream consumption, portal cleanup, error identity and a later server error. This is a reliability defect in error propagation, not a claim of a security vulnerability.
Activity