Skip to content

Commit eaf0b71

Browse files
zcolleenEygin Semen Leonidovich
and
Eygin Semen Leonidovich
authored
Bug fix: Mark connection as not good when error on cancellation confirmation (#68)
* Mark connection as not good when error on cancellation confirmation (cherry picked from commit c996b77) * tests added (cherry picked from commit 2258616) * query tests added (cherry picked from commit 2fc4276) * return ServerError when failed to get cancelation confirmation * fix ci tests Co-authored-by: Eygin Semen Leonidovich <[email protected]>
1 parent e2afc1a commit eaf0b71

File tree

2 files changed

+42
-2
lines changed

2 files changed

+42
-2
lines changed

queries_test.go

+41
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"context"
66
"database/sql"
77
"database/sql/driver"
8+
"errors"
89
"fmt"
910
"io"
1011
"log"
@@ -1387,6 +1388,46 @@ func TestProcessQueryErrors(t *testing.T) {
13871388
}
13881389
}
13891390

1391+
type mockReadWriteCloser struct {
1392+
io.ReadWriteCloser
1393+
}
1394+
1395+
func (*mockReadWriteCloser) Read([]byte) (int, error) { return 0, errors.New("fake err") }
1396+
1397+
func TestProcessQueryCancelConfirmationError(t *testing.T) {
1398+
tl := testLogger{t: t}
1399+
defer tl.StopLogging()
1400+
conn := internalConnection(t, &tl)
1401+
defer conn.Close()
1402+
1403+
stmt, err := conn.prepareContext(context.Background(), "select 1")
1404+
if err != nil {
1405+
t.Fatal("prepareContext expected to succeed, but it failed with", err)
1406+
}
1407+
err = stmt.sendQuery(context.Background(), []namedValue{})
1408+
if err != nil {
1409+
t.Fatal("sendQuery expected to succeed, but it failed with", err)
1410+
}
1411+
// mock real connection to imitate situation when you write but dont get response
1412+
conn.sess.buf.transport = &mockReadWriteCloser{ReadWriteCloser: conn.sess.buf.transport}
1413+
// canceling context to try to send attention request
1414+
ctx, cancel := context.WithCancel(context.Background())
1415+
cancel()
1416+
1417+
_, err = stmt.processQueryResponse(ctx)
1418+
if err == nil {
1419+
t.Error("processQueryResponse expected to fail but it succeeded")
1420+
}
1421+
// should not fail with ErrBadConn because query was successfully sent to server
1422+
if _, ok := err.(ServerError); !ok {
1423+
t.Error("processQueryResponse expected to fail with ServerError error but failed with other error: ", err)
1424+
}
1425+
1426+
if conn.connectionGood {
1427+
t.Fatal("Connection should be in a bad state")
1428+
}
1429+
}
1430+
13901431
func TestProcessQueryNextErrors(t *testing.T) {
13911432
tl := testLogger{t: t}
13921433
defer tl.StopLogging()

token.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package mssql
33
import (
44
"context"
55
"encoding/binary"
6-
"errors"
76
"fmt"
87
"io"
98
"io/ioutil"
@@ -967,7 +966,7 @@ func (t tokenProcessor) nextToken() (tokenStruct, error) {
967966
}
968967
// we did not get cancellation confirmation, something is not
969968
// right, this connection is not usable anymore
970-
return nil, errors.New("did not get cancellation confirmation from the server")
969+
return nil, ServerError{Error{Message: "did not get cancellation confirmation from the server"}}
971970
}
972971
}
973972

0 commit comments

Comments
 (0)