Skip to content

Commit 346b2e5

Browse files
author
Shabad Kirill
committed
changelog + codestyle
1 parent f4c1f39 commit 346b2e5

File tree

3 files changed

+77
-5
lines changed

3 files changed

+77
-5
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
* Fixed error catching in DoTxWithResult
2+
3+
## v3.115.2
4+
* Fixed bug with wrong literal YQL representation for signed integer YDB types
5+
6+
## v3.115.1
7+
* Added `ydb.Param.Range()` range iterator
8+
19
## v3.115.0
210
* Added public package `pkg/xtest` with test helpers
311

retry/sql.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,8 @@ func DoTxWithResult[T any](ctx context.Context, db *sql.DB,
222222
return zeroValue, xerrors.WithStackTrace(err)
223223
}
224224
if err = tx.Commit(); err != nil {
225-
return zeroValue, xerrors.WithStackTrace(err)
225+
// We create and use tx in this method, so if we catch this error, it means context cancellation
226+
return zeroValue, xerrors.WithStackTrace(transformCommitError(ctx, err))
226227
}
227228

228229
return v, nil
@@ -236,6 +237,16 @@ func DoTxWithResult[T any](ctx context.Context, db *sql.DB,
236237
return v, nil
237238
}
238239

240+
func transformCommitError(ctx context.Context, err error) error {
241+
if xerrors.Is(err, sql.ErrTxDone) {
242+
if ctxErr := ctx.Err(); ctxErr != nil {
243+
return ctxErr
244+
}
245+
}
246+
247+
return err
248+
}
249+
239250
func mustDeleteConn[T interface {
240251
*sql.Conn
241252
}](err error, conn T) bool {

retry/sql_test.go

Lines changed: 57 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,11 @@ import (
1818
)
1919

2020
type mockConnector struct {
21-
t testing.TB
22-
conns uint32
23-
queryErr error
24-
execErr error
21+
t testing.TB
22+
conns uint32
23+
queryErr error
24+
execErr error
25+
commitErr error
2526
}
2627

2728
var _ driver.Connector = &mockConnector{}
@@ -292,3 +293,55 @@ func TestCleanUpResourcesOnPanicInRetryOperation(t *testing.T) {
292293
})
293294
})
294295
}
296+
297+
func TestTxDoneErrorReturnsContextError(t *testing.T) {
298+
t.Run("DoTxWithResult", func(t *testing.T) {
299+
ctx, cancel := context.WithCancel(context.Background())
300+
301+
m := &mockConnector{
302+
t: t,
303+
commitErr: sql.ErrTxDone,
304+
}
305+
db := sql.OpenDB(m)
306+
307+
attempts := 0
308+
_, err := DoTxWithResult(ctx, db,
309+
func(ctx context.Context, tx *sql.Tx) (int, error) {
310+
attempts++
311+
cancel()
312+
time.Sleep(10 * time.Millisecond)
313+
314+
return 42, nil
315+
},
316+
)
317+
318+
require.Error(t, err)
319+
require.ErrorIs(t, err, context.Canceled)
320+
require.Equal(t, 1, attempts)
321+
})
322+
323+
t.Run("DoTx", func(t *testing.T) {
324+
ctx, cancel := context.WithCancel(context.Background())
325+
326+
m := &mockConnector{
327+
t: t,
328+
commitErr: sql.ErrTxDone,
329+
}
330+
db := sql.OpenDB(m)
331+
332+
attempts := 0
333+
err := DoTx(ctx, db,
334+
func(ctx context.Context, tx *sql.Tx) error {
335+
attempts++
336+
cancel()
337+
time.Sleep(10 * time.Millisecond)
338+
339+
return nil
340+
},
341+
)
342+
343+
require.Error(t, err)
344+
require.ErrorIs(t, err, context.Canceled)
345+
require.Equal(t, 1, attempts)
346+
})
347+
}

0 commit comments

Comments
 (0)