Skip to content

Commit 4a1fb5c

Browse files
[ASYNC] Apply #2236 to async code
1 parent a94e511 commit 4a1fb5c

File tree

2 files changed

+34
-2
lines changed

2 files changed

+34
-2
lines changed

src/snowflake/connector/aio/_cursor.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -685,7 +685,15 @@ async def execute(
685685
logger.debug(ret)
686686
err = ret["message"]
687687
code = ret.get("code", -1)
688-
if self._timebomb and self._timebomb.result():
688+
if (
689+
self._timebomb
690+
and self._timebomb.result()
691+
and "SQL execution canceled" in err
692+
):
693+
# Modify the error message only if the server error response indicates the query was canceled.
694+
# If the error occurs before the cancellation request reaches the backend
695+
# (e.g., due to a very short timeout), we retain the original error message
696+
# as the query might have encountered an issue prior to cancellation.
689697
err = (
690698
f"SQL execution was cancelled by the client due to a timeout. "
691699
f"Error message received from the server: {err}"

test/integ/aio/test_cursor_async.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
from datetime import date, datetime, timezone
1616
from typing import NamedTuple
1717
from unittest import mock
18+
from unittest.mock import MagicMock
1819

1920
import pytest
2021
import pytz
@@ -792,6 +793,7 @@ async def test_invalid_bind_data_type(conn_cnx):
792793
await cnx.cursor().execute("select 1 from dual where 1=%s", ([1, 2, 3],))
793794

794795

796+
@pytest.mark.skipolddriver
795797
async def test_timeout_query(conn_cnx):
796798
async with conn_cnx() as cnx:
797799
async with cnx.cursor() as c:
@@ -802,10 +804,32 @@ async def test_timeout_query(conn_cnx):
802804
)
803805
assert err.value.errno == 604, (
804806
"Invalid error code"
805-
and "SQL execution was cancelled by the client due to a timeout"
807+
and "SQL execution was cancelled by the client due to a timeout. Error message received from the server: SQL execution canceled"
806808
in err.value.msg
807809
)
808810

811+
with pytest.raises(errors.ProgrammingError) as err:
812+
# we can not precisely control the timing to send cancel query request right after server
813+
# executes the query but before returning the results back to client
814+
# it depends on python scheduling and server processing speed, so we mock here
815+
mock_timebomb = MagicMock()
816+
mock_timebomb.result.return_value = True
817+
818+
with mock.patch.object(c, "_timebomb", mock_timebomb):
819+
await c.execute(
820+
"select 123'",
821+
timeout=0.1,
822+
)
823+
assert (
824+
mock_timebomb.result.return_value is True and err.value.errno == 1003
825+
), (
826+
"Invalid error code"
827+
and "SQL compilation error:\nsyntax error line 1 at position 10 unexpected '''."
828+
in err.value.msg
829+
and "SQL execution was cancelled by the client due to a timeout"
830+
not in err.value.msg
831+
)
832+
809833

810834
async def test_executemany(conn, db_parameters):
811835
"""Executes many statements. Client binding is supported by either dict, or list data types.

0 commit comments

Comments
 (0)