Skip to content

Commit 4fc9e7d

Browse files
committed
CancelRequest: handle 'An existing connection was forcibly closed by the remote host' on Windows
1 parent 97adce2 commit 4fc9e7d

File tree

1 file changed

+17
-8
lines changed

1 file changed

+17
-8
lines changed

pgconn/pgconn.go

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -935,21 +935,30 @@ func (pgConn *PgConn) CancelRequest(ctx context.Context) error {
935935
buf := make([]byte, 16)
936936
binary.BigEndian.PutUint32(buf[0:4], 16)
937937
binary.BigEndian.PutUint32(buf[4:8], 80877102)
938-
binary.BigEndian.PutUint32(buf[8:12], uint32(pgConn.pid))
939-
binary.BigEndian.PutUint32(buf[12:16], uint32(pgConn.secretKey))
940-
_, err = cancelConn.Write(buf)
941-
if err != nil {
942-
return err
938+
binary.BigEndian.PutUint32(buf[8:12], pgConn.pid)
939+
binary.BigEndian.PutUint32(buf[12:16], pgConn.secretKey)
940+
941+
if _, err := cancelConn.Write(buf); err != nil {
942+
return fmt.Errorf("write to connection for cancellation: %w", err)
943943
}
944944

945-
_, err = cancelConn.Read(buf)
946-
if err != io.EOF {
947-
return err
945+
if _, err := cancelConn.Read(buf); err != nil {
946+
if errors.Is(err, io.EOF) || isConnectionClosedError(err) {
947+
return nil
948+
}
949+
950+
return fmt.Errorf("unexpected error while reading connection response: %w", err)
948951
}
949952

950953
return nil
951954
}
952955

956+
// isConnectionClosedError checks the error message to identify
957+
// the specific "forcibly closed" error that occurs on Windows.
958+
func isConnectionClosedError(err error) bool {
959+
return strings.Contains(err.Error(), "An existing connection was forcibly closed by the remote host")
960+
}
961+
953962
// WaitForNotification waits for a LISTON/NOTIFY message to be received. It returns an error if a notification was not
954963
// received.
955964
func (pgConn *PgConn) WaitForNotification(ctx context.Context) error {

0 commit comments

Comments
 (0)