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
When executing a context-aware operation during a transaction, different error types are returned depending on when the context is canceled.
In the following example:
tx, err := db.Begin()
if err != nil {
fmt.Printf("Failed to obtain db connection: %v", err)
return
}
returnedErrors := make(chan error, 1)
go func() {
_, err := tx.ExecContext(ctx, `INSERT INTO foo VALUES (3, "three")`)
returnedErrors <- err
}()
cancel()
err = <-returnedErrors
switch {
case errors.Is(err, ErrInvalidConn):
fmt.Printf("The context was canceled, but ExecContext got error %v", err)
case errors.Is(err, context.Canceled):
// cool
case err != nil:
fmt.Printf("Got unexpected error %v", err)
}
err = tx.Rollback()
switch {
case errors.Is(err, ErrInvalidConn):
fmt.Printf("The context was canceled, but ROLLBACK got error %v", err)
case errors.Is(err, context.Canceled):
// cool
case err != nil:
fmt.Printf("Got unexpected error %v", err)
}
The context may be canceled (1) before or during the ExecContext operation, (2) after the ExecContext operation returns, or (3) after the ExecContext operation succeeds but before the context is removed from the watcher.
(1) If the context is canceled before or during ExecContext, ExecContext returns the error as cached by the context watcher, returning context.Canceled.
(2) If the context is canceled after the ExecContext, no errors are returned, everything succeeds.
(3) !bug! If the context is canceled after the ExecContext operation succeeds but before the context is removed from the watcher, then tx.Rollback() or tx.Commit() return ErrInvalidConn.
I argue that the behavior in (3) should be consistent with the behavior in (1) - the error returned by tx.Rollback() or tx.Commit() should be context.Canceled. The connection being closed is a side effect of the root cause that the context passed to ExecContext has been canceled. (This is also a simpler fix than attempting to remove the race of a context being canceled after ExecContext's operation is successfully executed but before the context is removed from the watcher.)
In our application, we trigger alerts on unexpected errors like ErrInvalidConn, but log and do not alert on expected errors like context.Canceled. The Commit/Rollback behavior ends up causing alerts in our application.
The text was updated successfully, but these errors were encountered:
When executing a context-aware operation during a transaction, different error types are returned depending on when the context is canceled.
In the following example:
The context may be canceled (1) before or during the ExecContext operation, (2) after the ExecContext operation returns, or (3) after the ExecContext operation succeeds but before the context is removed from the watcher.
(1) If the context is canceled before or during ExecContext, ExecContext returns the error as cached by the context watcher, returning context.Canceled.
(2) If the context is canceled after the ExecContext, no errors are returned, everything succeeds.
(3) !bug! If the context is canceled after the ExecContext operation succeeds but before the context is removed from the watcher, then
tx.Rollback()
ortx.Commit()
return ErrInvalidConn.I argue that the behavior in (3) should be consistent with the behavior in (1) - the error returned by
tx.Rollback()
ortx.Commit()
should be context.Canceled. The connection being closed is a side effect of the root cause that the context passed to ExecContext has been canceled. (This is also a simpler fix than attempting to remove the race of a context being canceled after ExecContext's operation is successfully executed but before the context is removed from the watcher.)In our application, we trigger alerts on unexpected errors like ErrInvalidConn, but log and do not alert on expected errors like context.Canceled. The Commit/Rollback behavior ends up causing alerts in our application.
The text was updated successfully, but these errors were encountered: