From b662ab67677b11e1b31c4c159574ff57c8a65484 Mon Sep 17 00:00:00 2001 From: Jack Christensen Date: Sat, 9 Jul 2022 21:26:38 -0500 Subject: [PATCH] Better encode error message --- pgtype/pgtype.go | 26 +++++++++++++++++++++++--- query_test.go | 2 +- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/pgtype/pgtype.go b/pgtype/pgtype.go index 636b0954..50483fa7 100644 --- a/pgtype/pgtype.go +++ b/pgtype/pgtype.go @@ -1816,6 +1816,27 @@ func (plan *wrapMultiDimSliceEncodePlan) Encode(value any, buf []byte) (newBuf [ return plan.next.Encode(&w, buf) } +func newEncodeError(value any, m *Map, oid uint32, formatCode int16, err error) error { + var format string + switch formatCode { + case TextFormatCode: + format = "text" + case BinaryFormatCode: + format = "binary" + default: + format = fmt.Sprintf("unknown (%d)", formatCode) + } + + var dataTypeName string + if t, ok := m.oidToType[oid]; ok { + dataTypeName = t.Name + } else { + dataTypeName = "unknown type" + } + + return fmt.Errorf("unable to encode %#v into %s format for %s (OID %d): %s", value, format, dataTypeName, oid, err) +} + // Encode appends the encoded bytes of value to buf. If value is the SQL value NULL then append nothing and return // (nil, nil). The caller of Encode is responsible for writing the correct NULL value or the length of the data // written. @@ -1837,13 +1858,12 @@ func (m *Map) Encode(oid uint32, formatCode int16, value any, buf []byte) (newBu return m.Encode(oid, formatCode, v, buf) } - return nil, fmt.Errorf("unable to encode %#v into format code %d for OID %d", value, formatCode, oid) + return nil, newEncodeError(value, m, oid, formatCode, errors.New("cannot find encode plan")) } newBuf, err = plan.Encode(value, buf) if err != nil { - err = fmt.Errorf("unable to encode %#v into format code %d for OID %d: %v", value, formatCode, oid, err) - return nil, err + return nil, newEncodeError(value, m, oid, formatCode, err) } return newBuf, nil diff --git a/query_test.go b/query_test.go index 0c8b5fab..dad93eaf 100644 --- a/query_test.go +++ b/query_test.go @@ -984,7 +984,7 @@ func TestQueryRowErrors(t *testing.T) { {"select $1::badtype", []any{"Jack"}, []any{&actual.i16}, `type "badtype" does not exist`}, {"SYNTAX ERROR", []any{}, []any{&actual.i16}, "SQLSTATE 42601"}, {"select $1::text", []any{"Jack"}, []any{&actual.i16}, "cannot scan OID 25 in text format into *int16"}, - {"select $1::point", []any{int(705)}, []any{&actual.s}, "unable to encode 705 into format code 1 for OID 600"}, + {"select $1::point", []any{int(705)}, []any{&actual.s}, "unable to encode 705 into binary format for point (OID 600)"}, } for i, tt := range tests {