New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Error during Query inner exec is not observed until Close() #1634
Comments
Hmm... That is a little tricky. The only way I can think of for an error to be returned before the func TestQueryReturnsErrorEarlier(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
pgxtest.RunWithQueryExecModes(ctx, t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
rows, err := conn.Query(context.Background(), "select * from foobar")
require.Error(t, err)
require.Error(t, rows.Err())
rows.Close()
require.Error(t, rows.Err())
})
} I took a quick look to see if it could be changed at the I'm not totally against adding an But the way Would better / more documentation of this behavior be sufficient? |
This happened to us if the database was shutdown after receiving the query but before returning anything. The error that's returned is a shutdown error. It's very hard to reproduce by itself but when you're issuing hundreds or thousands of queries per second it will happen to several of them, at least from what we've seen in practice.
I agree. Unfortunately there's a lack of documentation in many places, including if rows != nil && err == nil && rows.FieldDescriptions() == nil { If we didn't need the field descriptions then this isn't as big of a deal because we would just do the normal The quickest solution would be to document that Longer-term it might be good to clarify the states that could be returned from Query(). As it stands, there might be better clarification around |
This is already the first paragraph of the docs for the // Query sends a query to the server and returns a Rows to read the results. Only errors encountered sending the query
// and initializing Rows will be returned. Err() on the returned Rows must be checked after the Rows is closed to
// determine if the query executed successfully. However, I added some additional documentation to that method and to the |
Thanks @jackc I appreciate the clarifications. |
Is your feature request related to a problem? Please describe.
Not a problem necessarily but behavior that could be improved in my opinion.
When
conn.Query
callsPgConn.ExecParams
orPgConn.ExecPrepared
they return a*ResultReader
that might be concluded and containing an error but the resulting Rows that is returned does not contain any error. Ideally an error would be returned from theQuery
call or at least an errored rows.To be honest, this is hard to test since it requires precise timing of the server erroring. But we were able to reproduce this scenario:
conn.Query
is calledPgConn.ExecParams
orPgConn.ExecPrepared
is calledPgConn.execExtendedSuffix
is calledResultReader.readUntilRowDescription
is calledpgConn.receiveMessage
returns a*pgproto3.ErrorResponse
which callsResultReader.concludeCommand
PgConn.ExecParams
orPgConn.ExecPrepared
now returns a concludedResultReader
with a stored errconn.Query
returns an unclosed*baseRows
(without anerr
set) and no errorbaseRows.Next()
returns falseErr()
returns non-nilThis was actually noticed because
FieldDescriptions
returned nil despiteErr()
returning nil which was confusing some code we have to map fields.Describe the solution you'd like
I think
conn.Query
could check if the command is concluded and there was an error and then callrows.fatal
.Describe alternatives you've considered
There isn't necessarily anything wrong with the current behavior but I would just say that it was unexpected that an error was encountered and yet
Err()
returned nil for the rows.Additional context
We are using this driver with Yugabyte. I don't think the code path above is yb-specific but we haven't tried to reproduce it with pg.
The text was updated successfully, but these errors were encountered: