Return connection errors from GetSelectedColumns and other pgx queries missing them - #4657
Conversation
Code reviewNo issues found. Checked for bugs and CLAUDE.md compliance. |
| var columnName string | ||
| if err := rows.Scan(&columnName); err != nil { | ||
| return nil, fmt.Errorf("error scanning column while getting selected columns: %w", err) | ||
| return nil, fmt.Errorf("error scanning column while getting selected columns for table %s: %w", sourceTable, err) |
There was a problem hiding this comment.
smth like this would be more handy:
columns, err := pgx.CollectRows[string](rows, pgx.RowTo)
if err != nil {
return nil, fmt.Errorf("error scanning columns while getting selected columns for table %s: %w", sourceTable, err)
}
return columns, nil
we already use CollectRows in postgres_source.go file
There was a problem hiding this comment.
can also leave instructions for agents in future to use CollectRows instead of raw Query + rows.Next + rows.Err != nil
There was a problem hiding this comment.
Good idea, full refactor sounded like too much for this but found a few other places not handling errors and turned them into CollectRows
🔄 Flaky Test DetectedAnalysis: A 20-minute package timeout panic — triggered by an environment-wide mirror-setup stall (79 tests hit UNEXPECTED STATUS TIMEOUT STATUS_SETUP) that let two MySQL server_id tests each consume their full 8-minute timeout budget — mass-failed ~100 tests with no correctness assertions failing, while the other two matrix legs passed on the same commit. ✅ Automatically retrying the workflow |
Error (sanitized)
Postgres snapshot partitions fail during
qreppull with a claim that the source table has no columns:The line emits
errorClass=OTHER/errorCode=UNKNOWNwith sourceother. It has appeared on several pipes across multiple regions over the past few weeks, always in a short burst that clears within minutes.Investigation
This a bug in PeerDB.
GetSelectedColumnsiteratespg_attributerows but never checksrows.Err(), so when the source connection dies after the query is sent,Nextstops immediately and the function returns an empty column list with a nil error.corePullQRepRecordsreads that empty list as "this table has no columns" and reports it, hiding the connection failure that actually happened.Conn.Query— documents thatQueryreturns before reading any rows, so a failure after the query is sent surfaces only throughRows.Err().57P01and57P03cover the backend terminations that the logs show at the same second as each burst.Every occurrence in the logs lands in the same second as the source connection dropping: a source restart refusing new connections, an administrator terminating the backend, or an SSH tunnel closing. Partitions for the same table succeed before and after each burst, which rules out a genuine all-columns-excluded configuration. Confidence is high: the pgx contract explains why the empty list appears, and the logs confirm the trigger in each case. Nobody needs to act on the message itself — the fix removes it, and the real connection error takes its place. Two things worth a reviewer's attention: a permanently misconfigured exclusion list would still produce the same message legitimately, and that case belongs in validation rather than here; and
SSH Tunnel Closed: EOFis matched by theio.EOFbranch before it reaches the SSH-tunnel branch, which predates this change.Change
GetSelectedColumnsnow checksrows.Err()after the iteration loop and wraps it aserror getting selected columns for table %s, matching the check its sibling function in the same file already performs.qreppull, table-schema fetch, and validation — previously read a truncated or empty list as fact; they now receive the underlying error.57P03and a closed tunnel asNOTIFY_CONNECTIVITY,57P01asNOTIFY_TERMINATE, a bareunexpected EOFasIGNORE_EOF. No classifier change is needed.Verification
TestGetSelectedColumnsReportsMidStreamConnectionLossbreaks a live connection after the query is sent and asserts thatGetSelectedColumnsreturns an error rather than an empty column list. It fails against the unfixed code with a nil error and zero columns, reproducing the production symptom exactly.OTHER.Resolves DBI-979