From a7375cc503268d34a0312d22c9c17f6e943f654b Mon Sep 17 00:00:00 2001 From: Craig Ringer Date: Fri, 11 Aug 2023 09:58:03 +1200 Subject: [PATCH] docs: Emphasise need to call rows.Err() after rows.Next() returns false The Rows interface in pgx, like its ancestor in database/sql, is easy to accidentally misuse in a way that can cause apps to misinterpret database or connection errors as successful queries with empty or truncated result-sets. Update the docs to emphasise the need to call rows.Err() after rows.Next() returns false, and direct users of the interface to the v5 API helpers that make writing correct code easier. The docs on Conn.Query() already call this out, so only a small change is needed to warn users and point them at the details on Query() Per details in #1707 --- rows.go | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/rows.go b/rows.go index 1b1c8ac9..ab8a12f8 100644 --- a/rows.go +++ b/rows.go @@ -17,7 +17,8 @@ import ( // the *Conn can be used again. Rows are closed by explicitly calling Close(), // calling Next() until it returns false, or when a fatal error occurs. // -// Once a Rows is closed the only methods that may be called are Close(), Err(), and CommandTag(). +// Once a Rows is closed the only methods that may be called are Close(), Err(), +// and CommandTag(). // // Rows is an interface instead of a struct to allow tests to mock Query. However, // adding a method to an interface is technically a breaking change. Because of this @@ -41,8 +42,15 @@ type Rows interface { FieldDescriptions() []pgconn.FieldDescription // Next prepares the next row for reading. It returns true if there is another - // row and false if no more rows are available. It automatically closes rows - // when all rows are read. + // row and false if no more rows are available or a fatal error has occurred. + // It automatically closes rows when all rows are read. + // + // Callers should check rows.Err() after rows.Next() returns false to detect + // whether result-set reading ended prematurely due to an error. See + // Conn.Query for details. + // + // For simpler error handling, consider using the higher-level pgx v5 + // CollectRows() and ForEachRow() helpers instead. Next() bool // Scan reads the values from the current row into dest values positionally.