Open aerialls opened 1 month ago
I'm not sure I understand the use case. In your example I would expect you to call Scan
and handle the returned error.
The reason errRows
has an Err()
method is to satisfy the Rows
interface. And the reason errRow
doesn't is because the Row
interface doesn't.
I'm using sqlc
and trying to add a global retry mechanism for a read-only connection. sqlc
is using the following interface as an entrypoint.
type DBTX interface {
Exec(context.Context, string, ...interface{}) (pgconn.CommandTag, error)
Query(context.Context, string, ...interface{}) (pgx.Rows, error)
QueryRow(context.Context, string, ...interface{}) pgx.Row
}
My initial idea was to create a RetriableDBTX
with the same interface as an entry-point for sqlc
and to retry the method in case of an error. It's working for Exec
and Query
but I don't have any error for QueryRow
and so my idea to be able to retrieve the error if we have an Err() error
method. The Scan
method is executed afterward by sqlc
for each SQL query so it's much harder to perform the retry logic here.
This change won't do what you want. And what you are doing with Query()
isn't reliable either.
Query()
will only return an error in limited circumstances such as a network failure sending the request. The returned Rows
has to be closed and Err()
checked to know if it successfully ran.
QueryRow()
is a very simple wrapper around Query()
. The result isn't actually read until Scan()
is called.
Add a dedicated method to extract error from
errRow
. This is already present forerrRows
. This allows the use case to extract the error to retry if necessary.