Repository: zeromicro/go-zero
Pull request #4060 (2024-04-10 03:52:13)

fix: timeout on query should return context.DeadlineExceeded

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/zeromicro/go-zero/pull/4060?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=zeromicro) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 95.17%. Comparing base [(`8690859`)](https://app.codecov.io/gh/zeromicro/go-zero/commit/8690859c7d1c9461bdc422c3c65608bde30904db?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=zeromicro) to head [(`877b994`)](https://app.codecov.io/gh/zeromicro/go-zero/pull/4060?dropdown=coverage&src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=zeromicro).
> Report is 7 commits behind head on master.

<details><summary>Additional details and impacted files</summary>



| [Files](https://app.codecov.io/gh/zeromicro/go-zero/pull/4060?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=zeromicro) | Coverage Δ | |
|---|---|---|
| [core/stores/sqlx/sqlconn.go](https://app.codecov.io/gh/zeromicro/go-zero/pull/4060?src=pr&el=tree&filepath=core%2Fstores%2Fsqlx%2Fsqlconn.go&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=zeromicro#diff-Y29yZS9zdG9yZXMvc3FseC9zcWxjb25uLmdv) | `100.00% <100.00%> (ø)` | |

... and [254 files with indirect coverage changes](https://app.codecov.io/gh/zeromicro/go-zero/pull/4060/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=zeromicro)

</details>

Patch:
diff --git a/core/stores/sqlx/sqlconn.go b/core/stores/sqlx/sqlconn.go
index d6ca746d..dfdb3f4b 100644
--- a/core/stores/sqlx/sqlconn.go
+++ b/core/stores/sqlx/sqlconn.go
@@ -296,7 +296,7 @@ func (db *commonSqlConn) queryRows(ctx context.Context, scanner func(*sql.Rows)
 
 		return query(ctx, conn, func(rows *sql.Rows) error {
 			e := scanner(rows)
-			if e != nil {
+			if e != nil && !errors.Is(e, context.DeadlineExceeded) {
 				scanFailed = true
 			}
 			return e


Test patch:
diff --git a/core/stores/sqlx/stmt_test.go b/core/stores/sqlx/stmt_test.go
index 84de7577..34f67206 100644
--- a/core/stores/sqlx/stmt_test.go
+++ b/core/stores/sqlx/stmt_test.go
@@ -4,6 +4,7 @@ import (
 	"context"
 	"database/sql"
 	"errors"
+	"strconv"
 	"testing"
 	"time"
 
@@ -290,6 +291,24 @@ func TestStmtBreaker(t *testing.T) {
 	})
 }
 
+func TestQueryScanTimeout(t *testing.T) {
+	dbtest.RunTest(t, func(db *sql.DB, mock sqlmock.Sqlmock) {
+		ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond)
+		defer cancel()
+		row := sqlmock.NewRows([]string{"foo"})
+		for i := 0; i < 10000; i++ {
+			row = row.AddRow("bar" + strconv.Itoa(i))
+		}
+		var val []struct {
+			Foo int
+			Bar string
+		}
+		conn := NewSqlConnFromDB(db)
+		err := conn.QueryRowsCtx(ctx, &val, "any")
+		assert.ErrorIs(t, err, context.DeadlineExceeded)
+	})
+}
+
 type mockedSessionConn struct {
 	lastInsertId int64
 	rowsAffected int64