Map io.EOF errors to io.ErrUnexpectedEOF
io.EOF is never expected during valid usage. In addition, database/sql uses io.EOF as a sentinal value that all rows from a query have been received. See https://github.com/jackc/pgx/issues/662.
This commit is contained in:
+9
-2
@@ -58,12 +58,19 @@ func (f *Frontend) Send(msg FrontendMessage) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func translateEOFtoErrUnexpectedEOF(err error) error {
|
||||||
|
if err == io.EOF {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// Receive receives a message from the backend.
|
// Receive receives a message from the backend.
|
||||||
func (f *Frontend) Receive() (BackendMessage, error) {
|
func (f *Frontend) Receive() (BackendMessage, error) {
|
||||||
if !f.partialMsg {
|
if !f.partialMsg {
|
||||||
header, err := f.cr.Next(5)
|
header, err := f.cr.Next(5)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, translateEOFtoErrUnexpectedEOF(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
f.msgType = header[0]
|
f.msgType = header[0]
|
||||||
@@ -73,7 +80,7 @@ func (f *Frontend) Receive() (BackendMessage, error) {
|
|||||||
|
|
||||||
msgBody, err := f.cr.Next(f.bodyLen)
|
msgBody, err := f.cr.Next(f.bodyLen)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, translateEOFtoErrUnexpectedEOF(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
f.partialMsg = false
|
f.partialMsg = false
|
||||||
|
|||||||
+24
-2
@@ -1,10 +1,11 @@
|
|||||||
package pgproto3_test
|
package pgproto3_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"io"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/jackc/pgproto3/v2"
|
"github.com/jackc/pgproto3/v2"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
type interruptReader struct {
|
type interruptReader struct {
|
||||||
@@ -13,7 +14,7 @@ type interruptReader struct {
|
|||||||
|
|
||||||
func (ir *interruptReader) Read(p []byte) (n int, err error) {
|
func (ir *interruptReader) Read(p []byte) (n int, err error) {
|
||||||
if len(ir.chunks) == 0 {
|
if len(ir.chunks) == 0 {
|
||||||
return 0, errors.New("no data")
|
return 0, io.EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
n = copy(p, ir.chunks[0])
|
n = copy(p, ir.chunks[0])
|
||||||
@@ -56,3 +57,24 @@ func TestFrontendReceiveInterrupted(t *testing.T) {
|
|||||||
t.Fatalf("unexpected msg: %v", msg)
|
t.Fatalf("unexpected msg: %v", msg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFrontendReceiveUnexpectedEOF(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
server := &interruptReader{}
|
||||||
|
server.push([]byte{'Z', 0, 0, 0, 5})
|
||||||
|
|
||||||
|
frontend := pgproto3.NewFrontend(pgproto3.NewChunkReader(server), nil)
|
||||||
|
|
||||||
|
msg, err := frontend.Receive()
|
||||||
|
if err == nil {
|
||||||
|
t.Fatal("expected err")
|
||||||
|
}
|
||||||
|
if msg != nil {
|
||||||
|
t.Fatalf("did not expect msg, but %v", msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
msg, err = frontend.Receive()
|
||||||
|
assert.Nil(t, msg)
|
||||||
|
assert.Equal(t, io.ErrUnexpectedEOF, err)
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,4 +5,5 @@ go 1.12
|
|||||||
require (
|
require (
|
||||||
github.com/jackc/chunkreader/v2 v2.0.0
|
github.com/jackc/chunkreader/v2 v2.0.0
|
||||||
github.com/jackc/pgio v1.0.0
|
github.com/jackc/pgio v1.0.0
|
||||||
|
github.com/stretchr/testify v1.4.0
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,4 +1,14 @@
|
|||||||
|
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/jackc/chunkreader/v2 v2.0.0 h1:DUwgMQuuPnS0rhMXenUtZpqZqrR/30NWY+qQvTpSvEs=
|
github.com/jackc/chunkreader/v2 v2.0.0 h1:DUwgMQuuPnS0rhMXenUtZpqZqrR/30NWY+qQvTpSvEs=
|
||||||
github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
|
github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
|
||||||
github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE=
|
github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE=
|
||||||
github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8=
|
github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||||
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||||
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
|||||||
Reference in New Issue
Block a user