From 286ecc8fe5f257edc79252181882455bb85f4b45 Mon Sep 17 00:00:00 2001 From: Colin Rogers <111200756+colin-rogers-dbt@users.noreply.github.com> Date: Fri, 1 Nov 2024 16:38:58 -0700 Subject: [PATCH] add InterfaceError to retryable_exceptions (#895) * add InterfaceError to retryable_exceptions * add changie * Add unit test --- .../unreleased/Fixes-20240806-163017.yaml | 6 ++++ dbt/adapters/redshift/connections.py | 1 + tests/unit/test_connection.py | 33 +++++++++++++++++++ 3 files changed, 40 insertions(+) create mode 100644 .changes/unreleased/Fixes-20240806-163017.yaml diff --git a/.changes/unreleased/Fixes-20240806-163017.yaml b/.changes/unreleased/Fixes-20240806-163017.yaml new file mode 100644 index 000000000..20b595930 --- /dev/null +++ b/.changes/unreleased/Fixes-20240806-163017.yaml @@ -0,0 +1,6 @@ +kind: Fixes +body: add InterfaceError to retryable_exceptions +time: 2024-08-06T16:30:17.348677-07:00 +custom: + Author: colin-rogers-dbt + Issue: "661" diff --git a/dbt/adapters/redshift/connections.py b/dbt/adapters/redshift/connections.py index d3fbcafea..521bcff86 100644 --- a/dbt/adapters/redshift/connections.py +++ b/dbt/adapters/redshift/connections.py @@ -382,6 +382,7 @@ def exponential_backoff(attempt: int): redshift_connector.OperationalError, redshift_connector.DatabaseError, redshift_connector.DataError, + redshift_connector.InterfaceError, ] open_connection = cls.retry_connection( diff --git a/tests/unit/test_connection.py b/tests/unit/test_connection.py index 17a676286..61df7a47e 100644 --- a/tests/unit/test_connection.py +++ b/tests/unit/test_connection.py @@ -1,5 +1,8 @@ from multiprocessing import get_context from unittest import TestCase, mock + +import pytest +from dbt.adapters.exceptions import FailedToConnectError from unittest.mock import MagicMock, call import redshift_connector @@ -7,6 +10,7 @@ from dbt.adapters.redshift import ( Plugin as RedshiftPlugin, RedshiftAdapter, + RedshiftCredentials, ) from tests.unit.utils import ( config_from_parts_or_dicts, @@ -128,3 +132,32 @@ def test_backend_pid_used_in_pg_terminate_backend(self): call(f"select pg_terminate_backend({backend_pid})"), ] ) + + def test_retry_able_exceptions_trigger_retry(self): + with mock.patch.object(self.adapter.connections, "add_query") as add_query: + connection_mock = mock_connection("model", state="closed") + connection_mock.credentials = RedshiftCredentials.from_dict( + { + "type": "redshift", + "dbname": "redshift", + "user": "root", + "host": "thishostshouldnotexist.test.us-east-1", + "pass": "password", + "port": 5439, + "schema": "public", + "retries": 2, + } + ) + + connect_mock = MagicMock() + connect_mock.side_effect = [ + redshift_connector.InterfaceError("retryable interface error<1>"), + redshift_connector.InterfaceError("retryable interface error<2>"), + redshift_connector.InterfaceError("retryable interface error<3>"), + ] + + with mock.patch("redshift_connector.connect", connect_mock): + with pytest.raises(FailedToConnectError) as e: + connection = self.adapter.connections.open(connection_mock) + assert str(e.value) == "Database Error\n retryable interface error<3>" + assert connect_mock.call_count == 3