| 
51 | 51 | try:  | 
52 | 52 |     import snowflake.connector.vendored.urllib3.contrib.pyopenssl  | 
53 | 53 |     from snowflake.connector.vendored import requests, urllib3  | 
 | 54 | +    from snowflake.connector.vendored.requests.exceptions import SSLError  | 
54 | 55 | except ImportError:  # pragma: no cover  | 
55 | 56 |     import requests  | 
56 | 57 |     import urllib3  | 
 | 58 | +    from requests.exceptions import SSLError  | 
57 | 59 | 
 
  | 
58 | 60 | THIS_DIR = os.path.dirname(os.path.realpath(__file__))  | 
59 | 61 | 
 
  | 
@@ -477,3 +479,58 @@ def test_retry_request_timeout(mockSessionRequest, next_action_result):  | 
477 | 479 |     # 13 seconds should be enough for authenticator to attempt thrice  | 
478 | 480 |     # however, loosen restrictions to avoid thread scheduling causing failure  | 
479 | 481 |     assert 1 < mockSessionRequest.call_count < 5  | 
 | 482 | + | 
 | 483 | + | 
 | 484 | +def test_sslerror_with_econnreset_retries():  | 
 | 485 | +    """Test that SSLError with ECONNRESET raises RetryRequest."""  | 
 | 486 | +    connection = mock_connection()  | 
 | 487 | +    connection.errorhandler = Error.default_errorhandler  | 
 | 488 | +    rest = SnowflakeRestful(  | 
 | 489 | +        host="testaccount.snowflakecomputing.com",  | 
 | 490 | +        port=443,  | 
 | 491 | +        connection=connection,  | 
 | 492 | +    )  | 
 | 493 | + | 
 | 494 | +    default_parameters = {  | 
 | 495 | +        "method": "POST",  | 
 | 496 | +        "full_url": "https://testaccount.snowflakecomputing.com/",  | 
 | 497 | +        "headers": {},  | 
 | 498 | +        "data": '{"code": 12345}',  | 
 | 499 | +        "token": None,  | 
 | 500 | +    }  | 
 | 501 | + | 
 | 502 | +    # Test SSLError with ECONNRESET in the message  | 
 | 503 | +    econnreset_ssl_error = SSLError("Connection broken: ECONNRESET")  | 
 | 504 | +    session = MagicMock()  | 
 | 505 | +    session.request = Mock(side_effect=econnreset_ssl_error)  | 
 | 506 | + | 
 | 507 | +    with pytest.raises(RetryRequest, match="Connection broken: ECONNRESET"):  | 
 | 508 | +        rest._request_exec(session=session, **default_parameters)  | 
 | 509 | + | 
 | 510 | + | 
 | 511 | +def test_sslerror_without_econnreset_does_not_retry():  | 
 | 512 | +    """Test that SSLError without ECONNRESET does not retry but raises OperationalError."""  | 
 | 513 | +    connection = mock_connection()  | 
 | 514 | +    connection.errorhandler = Error.default_errorhandler  | 
 | 515 | +    rest = SnowflakeRestful(  | 
 | 516 | +        host="testaccount.snowflakecomputing.com",  | 
 | 517 | +        port=443,  | 
 | 518 | +        connection=connection,  | 
 | 519 | +    )  | 
 | 520 | + | 
 | 521 | +    default_parameters = {  | 
 | 522 | +        "method": "POST",  | 
 | 523 | +        "full_url": "https://testaccount.snowflakecomputing.com/",  | 
 | 524 | +        "headers": {},  | 
 | 525 | +        "data": '{"code": 12345}',  | 
 | 526 | +        "token": None,  | 
 | 527 | +    }  | 
 | 528 | + | 
 | 529 | +    # Test SSLError without ECONNRESET in the message  | 
 | 530 | +    regular_ssl_error = SSLError("SSL handshake failed")  | 
 | 531 | +    session = MagicMock()  | 
 | 532 | +    session.request = Mock(side_effect=regular_ssl_error)  | 
 | 533 | + | 
 | 534 | +    # This should raise OperationalError, not RetryRequest  | 
 | 535 | +    with pytest.raises(OperationalError):  | 
 | 536 | +        rest._request_exec(session=session, **default_parameters)  | 
0 commit comments