-
Type: Task
-
Resolution: Fixed
-
Priority: Major - P3
-
Affects Version/s: None
-
Component/s: None
-
None
-
Go Drivers
-
Not Needed
-
Context
REP-3632 alters mongosync’s custom Context implementation so that its Err() returns a wrapper that includes the error’s Cause. The Go driver, though, seems to throw away that wrapper.
For example here the driver checks if ctx.Err() is Canceled, and if so, it returns a hard-coded Canceled … even though the error check uses errors.Is() in order to (correctly) handle wrapped errors.
To give a more concrete example: if the context’s Err() returns `context canceled: migration completed successfully`, the driver’s returned error is just `context canceled`.
Definition of done
It would be nice to preserve the wrapper.
While we recognize that it’s a “stretch” for mongosync’s Context.Err() implementation to return a wrapper error instead of, e.g., context.Canceled, the “spirit” of using errors.Is() seems to be that wrappers should be able to substitute for wrapped errors, more or less arbitrarily.
Potential changeset:
diff --git a/x/mongo/driver/topology/connection.go b/x/mongo/driver/topology/connection.go index 00f44bee..d1a4f726 100644 --- a/x/mongo/driver/topology/connection.go +++ b/x/mongo/driver/topology/connection.go @@ -318,7 +318,7 @@ func transformNetworkError(ctx context.Context, originalError error, contextDead // If there was an error and the context was cancelled, we assume it happened due to the cancellation. if errors.Is(ctx.Err(), context.Canceled) { - return context.Canceled + return ctx.Err() } // If there was a timeout error and the context deadline was used, we convert the error into @@ -327,7 +327,7 @@ func transformNetworkError(ctx context.Context, originalError error, contextDead return originalError } if netErr, ok := originalError.(net.Error); ok && netErr.Timeout() { - return context.DeadlineExceeded + return fmt.Errorf("%w: %w", originalError, context.DeadlineExceeded) } return originalError
Pitfalls
None? Clients who submit stdlib Context structs will be unaffected.