diff options
author | Daniel Theophanes <kardianos@gmail.com> | 2018-10-27 14:12:52 -0700 |
---|---|---|
committer | Daniel Theophanes <kardianos@gmail.com> | 2018-10-29 16:11:22 +0000 |
commit | cf6e4238b63a180abd5a390dc8f11d50f024ba35 (patch) | |
tree | 820a76602dd6b1743e75f9f43f07b25683d26e02 /src/database | |
parent | 37afd3e31100a06229da61549abf5210a1dae8d0 (diff) | |
download | go-git-cf6e4238b63a180abd5a390dc8f11d50f024ba35.tar.gz |
database/sql: prefer to return Rows.lasterr rather then a static error
Fixes #25829
Change-Id: I400fdaf0ef3a23bc0d61c4873ffa298e0cf0fc6a
Reviewed-on: https://go-review.googlesource.com/c/145204
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Diffstat (limited to 'src/database')
-rw-r--r-- | src/database/sql/sql.go | 28 |
1 files changed, 19 insertions, 9 deletions
diff --git a/src/database/sql/sql.go b/src/database/sql/sql.go index 1ffe252ee3..31db7a47d6 100644 --- a/src/database/sql/sql.go +++ b/src/database/sql/sql.go @@ -2605,6 +2605,15 @@ type Rows struct { lastcols []driver.Value } +// lasterrOrErrLocked returns either lasterr or the provided err. +// rs.closemu must be read-locked. +func (rs *Rows) lasterrOrErrLocked(err error) error { + if rs.lasterr != nil && rs.lasterr != io.EOF { + return rs.lasterr + } + return err +} + func (rs *Rows) initContextClose(ctx, txctx context.Context) { if ctx.Done() == nil && (txctx == nil || txctx.Done() == nil) { return @@ -2728,22 +2737,22 @@ func (rs *Rows) NextResultSet() bool { func (rs *Rows) Err() error { rs.closemu.RLock() defer rs.closemu.RUnlock() - if rs.lasterr == io.EOF { - return nil - } - return rs.lasterr + return rs.lasterrOrErrLocked(nil) } +var errRowsClosed = errors.New("sql: Rows are closed") +var errNoRows = errors.New("sql: no Rows available") + // Columns returns the column names. // Columns returns an error if the rows are closed. func (rs *Rows) Columns() ([]string, error) { rs.closemu.RLock() defer rs.closemu.RUnlock() if rs.closed { - return nil, errors.New("sql: Rows are closed") + return nil, rs.lasterrOrErrLocked(errRowsClosed) } if rs.rowsi == nil { - return nil, errors.New("sql: no Rows available") + return nil, rs.lasterrOrErrLocked(errNoRows) } rs.dc.Lock() defer rs.dc.Unlock() @@ -2757,10 +2766,10 @@ func (rs *Rows) ColumnTypes() ([]*ColumnType, error) { rs.closemu.RLock() defer rs.closemu.RUnlock() if rs.closed { - return nil, errors.New("sql: Rows are closed") + return nil, rs.lasterrOrErrLocked(errRowsClosed) } if rs.rowsi == nil { - return nil, errors.New("sql: no Rows available") + return nil, rs.lasterrOrErrLocked(errNoRows) } rs.dc.Lock() defer rs.dc.Unlock() @@ -2916,8 +2925,9 @@ func (rs *Rows) Scan(dest ...interface{}) error { return rs.lasterr } if rs.closed { + err := rs.lasterrOrErrLocked(errRowsClosed) rs.closemu.RUnlock() - return errors.New("sql: Rows are closed") + return err } rs.closemu.RUnlock() |