Fix: import ExecutableError from dbt_common and chain original exception in cursor.py - #689
Open
tbrandharrity wants to merge 1 commit into
Open
Conversation
… exception The Glue cursor's execute() catches broad exceptions and re-raises as dbterrors.ExecutableError, but dbt.exceptions.ExecutableError does not exist in dbt-core >= 1.5 -- ExecutableError lives in dbt_common.exceptions. Current behavior: any transient Glue error (network timeout, throttle, etc.) triggers the except block, and the raise itself crashes with `module 'dbt.exceptions' has no attribute 'ExecutableError'`. This obscures the ORIGINAL error and turns recoverable transients into fatal build failures. Fix: 1. Import ExecutableError from dbt_common.exceptions (matching connection.py which was fixed the same way). 2. Raise ExecutableError(str(e)) from e so the original exception is preserved in the traceback. Test: no unit test currently exercises this path; the bug only surfaces on real Glue transient failures which are hard to reproduce deterministically in tests.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
GlueCursor.execute()catches any exception (typically transient Glue errors — network timeouts, throttles, session drops) and attempts to re-raise asdbterrors.ExecutableError. However,dbt.exceptions.ExecutableErrordoes not exist in dbt-core ≥ 1.5 —ExecutableErrorlives indbt_common.exceptions(which the siblingconnection.pycorrectly imports).Current behavior: the
exceptblock fires, then theraiseitself crashes with:This has two consequences:
Reproduced on
dbt-glue==1.10.19withdbt-core==1.10.21when a Glue interactive session had a transient AWS SDK Read timeout duringcreateTable. Killed a 3-hour build.Fix
Two-line change to
dbt/adapters/glue/gluedbapi/cursor.py:ExecutableErrorfromdbt_common.exceptions(extending the existingDbtDatabaseErrorimport).raise ExecutableError(str(e)) from einstead of the brokenraise dbterrors.ExecutableError— preserves the original exception in the traceback via PEP 3134 exception chaining.Matches the same fix that was applied to
connection.pyin #434.Tests
No existing unit test exercises this code path. The bug only surfaces on real transient Glue failures, which are hard to trigger deterministically in tests. Existing test suite still passes.
Happy to add a test if maintainers can suggest the right mock pattern (mocking
self.statement.execute()to raise an arbitrary exception, then assertingExecutableErroris raised with the original in__cause__).