diff --git a/queries_test.go b/queries_test.go index 20bcfb6c..fa635be1 100644 --- a/queries_test.go +++ b/queries_test.go @@ -5,6 +5,7 @@ import ( "context" "database/sql" "database/sql/driver" + "errors" "fmt" "io" "log" @@ -1387,6 +1388,46 @@ func TestProcessQueryErrors(t *testing.T) { } } +type mockReadWriteCloser struct { + io.ReadWriteCloser +} + +func (*mockReadWriteCloser) Read([]byte) (int, error) { return 0, errors.New("fake err") } + +func TestProcessQueryCancelConfirmationError(t *testing.T) { + tl := testLogger{t: t} + defer tl.StopLogging() + conn := internalConnection(t, &tl) + defer conn.Close() + + stmt, err := conn.prepareContext(context.Background(), "select 1") + if err != nil { + t.Fatal("prepareContext expected to succeed, but it failed with", err) + } + err = stmt.sendQuery(context.Background(), []namedValue{}) + if err != nil { + t.Fatal("sendQuery expected to succeed, but it failed with", err) + } + // mock real connection to imitate situation when you write but dont get response + conn.sess.buf.transport = &mockReadWriteCloser{ReadWriteCloser: conn.sess.buf.transport} + // canceling context to try to send attention request + ctx, cancel := context.WithCancel(context.Background()) + cancel() + + _, err = stmt.processQueryResponse(ctx) + if err == nil { + t.Error("processQueryResponse expected to fail but it succeeded") + } + // should not fail with ErrBadConn because query was successfully sent to server + if _, ok := err.(ServerError); !ok { + t.Error("processQueryResponse expected to fail with ServerError error but failed with other error: ", err) + } + + if conn.connectionGood { + t.Fatal("Connection should be in a bad state") + } +} + func TestProcessQueryNextErrors(t *testing.T) { tl := testLogger{t: t} defer tl.StopLogging() diff --git a/token.go b/token.go index 5f9e8202..7d222307 100644 --- a/token.go +++ b/token.go @@ -3,7 +3,6 @@ package mssql import ( "context" "encoding/binary" - "errors" "fmt" "io" "io/ioutil" @@ -959,7 +958,7 @@ func (t tokenProcessor) nextToken() (tokenStruct, error) { } // we did not get cancellation confirmation, something is not // right, this connection is not usable anymore - return nil, errors.New("did not get cancellation confirmation from the server") + return nil, ServerError{Error{Message: "did not get cancellation confirmation from the server"}} } }