From f9f57c44430c3449a71533e78f25e88aa4c06a65 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Tim=20M=C3=B6hlmann?= Date: Fri, 10 Jan 2020 12:06:53 +0200 Subject: [PATCH] database/sql: add method Err on sql.Row The Row.Err method is intended to assist wrapping sql.DB. Because sql.Row is a struct with private fields, a wrapper in an existing code base cannot easily provide users with a different implementation without large rewrites. Adding this method allows query level errors to be handled centrally. Fixes #35804 Change-Id: I94e6329de89a7ee1284ce9ef76af4363d2d081f9 Reviewed-on: https://go-review.googlesource.com/c/go/+/214317 Reviewed-by: Daniel Theophanes Run-TryBot: Daniel Theophanes TryBot-Result: Gobot Gobot --- src/database/sql/sql.go | 8 ++++++++ src/database/sql/sql_test.go | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/src/database/sql/sql.go b/src/database/sql/sql.go index 1bf3731b00..95906b1318 100644 --- a/src/database/sql/sql.go +++ b/src/database/sql/sql.go @@ -3174,6 +3174,14 @@ func (r *Row) Scan(dest ...interface{}) error { return r.rows.Close() } +// Err provides a way for wrapping packages to check for +// query errors without calling Scan. +// Err returns the error, if any, that was encountered while running the query. +// If this error is not nil, this error will also be returned from Scan. +func (r *Row) Err() error { + return r.err +} + // A Result summarizes an executed SQL command. type Result interface { // LastInsertId returns the integer generated by the database diff --git a/src/database/sql/sql_test.go b/src/database/sql/sql_test.go index a1437c46c9..0fc994d0a1 100644 --- a/src/database/sql/sql_test.go +++ b/src/database/sql/sql_test.go @@ -788,6 +788,24 @@ func TestQueryRow(t *testing.T) { } } +func TestRowErr(t *testing.T) { + db := newTestDB(t, "people") + + err := db.QueryRowContext(context.Background(), "SELECT|people|bdate|age=?", 3).Err() + if err != nil { + t.Errorf("Unexpected err = %v; want %v", err, nil) + } + + ctx, cancel := context.WithCancel(context.Background()) + cancel() + + err = db.QueryRowContext(ctx, "SELECT|people|bdate|age=?", 3).Err() + exp := "context canceled" + if err == nil || !strings.Contains(err.Error(), exp) { + t.Errorf("Expected err = %v; got %v", exp, err) + } +} + func TestTxRollbackCommitErr(t *testing.T) { db := newTestDB(t, "people") defer closeDB(t, db) -- 2.50.0