From 9c5c1cd9564993e6638bef940f814f2322933d33 Mon Sep 17 00:00:00 2001 From: Colin Date: Tue, 6 Aug 2024 16:29:34 -0700 Subject: [PATCH 1/3] add InterfaceError to retryable_exceptions --- dbt/adapters/redshift/connections.py | 1 + 1 file changed, 1 insertion(+) 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( From ad1d794e5b985111bbc86cbaff65173e8dbd7d1d Mon Sep 17 00:00:00 2001 From: Colin Date: Tue, 6 Aug 2024 16:30:34 -0700 Subject: [PATCH 2/3] add changie --- .changes/unreleased/Fixes-20240806-163017.yaml | 6 ++++++ 1 file changed, 6 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" From 7dcb426b8e334b61e51023b1fe48dcc9bec2e1e7 Mon Sep 17 00:00:00 2001 From: Colin Date: Fri, 1 Nov 2024 11:24:03 -0700 Subject: [PATCH 3/3] Add unit test --- tests/unit/test_connection.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) 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