Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,10 @@ func (d *Driver) connect(ctx context.Context) error {
if d.metaBalancer.balancer == nil {
b, err := balancer.New(ctx, d.config, d.pool, d.discoveryOptions...)
if err != nil {
// Don't wrap context errors with stack trace - let higher levels handle them
if xerrors.IsContextError(err) {
return err
}
return xerrors.WithStackTrace(err)
}
d.metaBalancer.balancer = b
Expand Down
37 changes: 37 additions & 0 deletions driver_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package ydb

import (
"context"
"testing"
"time"

"github.com/stretchr/testify/require"
)

func TestOpenWithExpiredContext(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Nanosecond)
defer cancel()

time.Sleep(10 * time.Nanosecond)

_, err := Open(ctx, "grpc://localhost:2136/local")
require.Error(t, err)
require.ErrorIs(t, err, context.DeadlineExceeded)
require.Contains(t, err.Error(), "context deadline exceeded")
require.Contains(t, err.Error(), "Open(driver.go:")
// Verify that the error doesn't have multiple stack traces (no "retry failed on attempt")
require.NotContains(t, err.Error(), "retry failed")
}

func TestOpenWithCanceledContext(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
cancel() // Cancel immediately

_, err := Open(ctx, "grpc://localhost:2136/local")
require.Error(t, err)
require.ErrorIs(t, err, context.Canceled)
require.Contains(t, err.Error(), "context canceled")
require.Contains(t, err.Error(), "Open(driver.go:")
// Verify that the error doesn't have multiple stack traces (no "retry failed on attempt")
require.NotContains(t, err.Error(), "retry failed")
}
4 changes: 4 additions & 0 deletions internal/balancer/balancer.go
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,10 @@ func New(ctx context.Context, driverConfig *config.Config, pool *conn.Pool, opts
} else {
// initialization of balancer state
if err := b.clusterDiscovery(ctx); err != nil {
// Don't wrap context errors with stack trace - let higher levels handle them
if xerrors.IsContextError(err) {
return nil, err
}
return nil, xerrors.WithStackTrace(err)
}
// run background discovering
Expand Down
10 changes: 10 additions & 0 deletions retry/retry.go
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,10 @@ func Retry(ctx context.Context, op retryOperation, opts ...Option) (finalErr err
return nil, nil //nolint:nilnil
}, opts...)
if err != nil {
// Don't wrap context errors with stack trace - let higher levels handle them
if xerrors.IsContextError(err) {
return err
}
return xerrors.WithStackTrace(err)
}

Expand Down Expand Up @@ -329,6 +333,12 @@ func RetryWithResult[T any](ctx context.Context, //nolint:revive,funlen
defer func() {
onDone(attempts, finalErr)
}()
// Check if context is already done before entering retry loop
select {
case <-ctx.Done():
return zeroValue, ctx.Err()
default:
}
for {
i++
attempts++
Expand Down