1
0
mirror of https://github.com/jackc/pgx.git synced 2025-04-28 05:37:41 +00:00

Rows.Scan errors now include which argument caused error

This commit is contained in:
Jack Christensen 2015-11-20 14:02:49 -06:00
parent dd26ad0091
commit edfdaf15c6
4 changed files with 23 additions and 7 deletions

@ -1,3 +1,7 @@
# Tip
* Rows.Scan errors now include which argument caused error
# 2.7.1 (October 26, 2015) # 2.7.1 (October 26, 2015)
* Disable SSL renegotiation * Disable SSL renegotiation

@ -214,6 +214,15 @@ func (rows *Rows) nextColumn() (*ValueReader, bool) {
return &rows.vr, true return &rows.vr, true
} }
type scanArgError struct {
col int
err error
}
func (e scanArgError) Error() string {
return fmt.Sprintf("can't scan into dest[%d]: %v", e.col, e.err)
}
// Scan reads the values from the current row into dest values positionally. // Scan reads the values from the current row into dest values positionally.
// dest can include pointers to core types, values implementing the Scanner // dest can include pointers to core types, values implementing the Scanner
// interface, and []byte. []byte will skip the decoding process and directly // interface, and []byte. []byte will skip the decoding process and directly
@ -225,7 +234,7 @@ func (rows *Rows) Scan(dest ...interface{}) (err error) {
return err return err
} }
for _, d := range dest { for i, d := range dest {
vr, _ := rows.nextColumn() vr, _ := rows.nextColumn()
// Check for []byte first as we allow sidestepping the decoding process and retrieving the raw bytes // Check for []byte first as we allow sidestepping the decoding process and retrieving the raw bytes
@ -244,7 +253,7 @@ func (rows *Rows) Scan(dest ...interface{}) (err error) {
} else if s, ok := d.(Scanner); ok { } else if s, ok := d.(Scanner); ok {
err = s.Scan(vr) err = s.Scan(vr)
if err != nil { if err != nil {
rows.Fatal(err) rows.Fatal(scanArgError{col: i, err: err})
} }
} else if vr.Type().DataType == JsonOid || vr.Type().DataType == JsonbOid { } else if vr.Type().DataType == JsonOid || vr.Type().DataType == JsonbOid {
decodeJson(vr, &d) decodeJson(vr, &d)
@ -292,7 +301,7 @@ func (rows *Rows) Scan(dest ...interface{}) (err error) {
case TimestampOid: case TimestampOid:
*v = decodeTimestamp(vr) *v = decodeTimestamp(vr)
default: default:
rows.Fatal(fmt.Errorf("Can't convert OID %v to time.Time", vr.Type().DataType)) rows.Fatal(scanArgError{col: i, err: fmt.Errorf("Can't convert OID %v to time.Time", vr.Type().DataType)})
} }
case *net.IPNet: case *net.IPNet:
*v = decodeInet(vr) *v = decodeInet(vr)
@ -319,12 +328,12 @@ func (rows *Rows) Scan(dest ...interface{}) (err error) {
} }
} }
} }
rows.Fatal(fmt.Errorf("Scan cannot decode into %T", d)) rows.Fatal(scanArgError{col: i, err: fmt.Errorf("Scan cannot decode into %T", d)})
} }
} }
if vr.Err() != nil { if vr.Err() != nil {
rows.Fatal(vr.Err()) rows.Fatal(scanArgError{col: i, err: vr.Err()})
} }
if rows.Err() != nil { if rows.Err() != nil {

@ -161,6 +161,10 @@ func TestConnQueryReadWrongTypeError(t *testing.T) {
t.Fatal("Expected Rows to have an error after an improper read but it didn't") t.Fatal("Expected Rows to have an error after an improper read but it didn't")
} }
if rows.Err().Error() != "can't scan into dest[0]: Can't convert OID 23 to time.Time" {
t.Fatalf("Expected different Rows.Err(): %v", rows.Err())
}
ensureConnValid(t, conn) ensureConnValid(t, conn)
} }

@ -1,7 +1,6 @@
package pgx_test package pgx_test
import ( import (
"encoding/json"
"github.com/jackc/pgx" "github.com/jackc/pgx"
"net" "net"
"reflect" "reflect"
@ -196,7 +195,7 @@ func testJsonInt16ArrayFailureDueToOverflow(t *testing.T, conn *pgx.Conn, typena
input := []int{1, 2, 234432} input := []int{1, 2, 234432}
var output []int16 var output []int16
err := conn.QueryRow("select $1::"+typename, input).Scan(&output) err := conn.QueryRow("select $1::"+typename, input).Scan(&output)
if _, ok := err.(*json.UnmarshalTypeError); !ok { if err.Error() != "can't scan into dest[0]: json: cannot unmarshal number 234432 into Go value of type int16" {
t.Errorf("%s: Expected *json.UnmarkalTypeError, but got %v", typename, err) t.Errorf("%s: Expected *json.UnmarkalTypeError, but got %v", typename, err)
} }
} }