-
Notifications
You must be signed in to change notification settings - Fork 122
fix: improve error messages for platform credential expiry in Semantic Layer tools #714
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
psaikaushik
wants to merge
3
commits into
dbt-labs:main
Choose a base branch
from
psaikaushik:fix/670-platform-credential-error-message
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
6ffb4bd
fix: improve error messages for platform credential expiry in Semanti…
psaikaushik bf4c678
chore: fix changie entry kind from Fixed to Bug Fix for issue 670
psaikaushik 8c6c4ff
fix: apply ruff formatting and fix QueryFailedError signature in tests
psaikaushik File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| kind: Bug Fix | ||
| body: Improve error messages when dbt Cloud platform credentials expire for Semantic Layer tools (query_metrics, execute_sql). The error now clearly indicates this is a platform-side issue and directs users to the dbt Cloud UI to refresh their development credentials. | ||
| time: 2026-04-12T21:00:00.000000-07:00 |
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
120 changes: 120 additions & 0 deletions
120
tests/unit/semantic_layer/test_platform_credential_errors.py
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,120 @@ | ||
| """Tests for platform credential error detection in Semantic Layer tools. | ||
|
|
||
| Verifies that when query_metrics or get_metrics_compiled_sql fail due to | ||
| expired dbt Cloud platform credentials, the error message clearly indicates | ||
| this is a platform-side issue and directs users to the dbt Cloud UI. | ||
|
|
||
| Related: https://github.com/dbt-labs/dbt-mcp/issues/670 | ||
| """ | ||
|
|
||
| import pytest | ||
|
|
||
| from dbt_mcp.semantic_layer.client import ( | ||
| SemanticLayerFetcher, | ||
| _PLATFORM_CREDENTIAL_HINT, | ||
| _is_platform_credential_error, | ||
| ) | ||
|
|
||
|
|
||
| @pytest.fixture | ||
| def fetcher(): | ||
| from unittest.mock import AsyncMock | ||
|
|
||
| return SemanticLayerFetcher(client_provider=AsyncMock()) | ||
|
|
||
|
|
||
| class TestPlatformCredentialErrorDetection: | ||
| """Tests for _is_platform_credential_error.""" | ||
|
|
||
| def test_detects_sso_authentication_expired(self) -> None: | ||
| assert _is_platform_credential_error( | ||
| "SSO authentication has expired, please re-connect to Snowflake" | ||
| ) | ||
|
|
||
| def test_detects_reconnect_to_snowflake(self) -> None: | ||
| assert _is_platform_credential_error( | ||
| "Please re-connect to Snowflake: https://docs.getdbt.com/faqs" | ||
| ) | ||
|
|
||
| def test_detects_refresh_snowflake_oauth_url(self) -> None: | ||
| assert _is_platform_credential_error( | ||
| "https://docs.getdbt.com/faqs/Troubleshooting/refresh-snowflake-oauth-credentials" | ||
| ) | ||
|
|
||
| def test_detects_authentication_token_expired(self) -> None: | ||
| assert _is_platform_credential_error( | ||
| "Authentication token has expired for the data warehouse" | ||
| ) | ||
|
|
||
| def test_detects_oauth_token_expired(self) -> None: | ||
| assert _is_platform_credential_error( | ||
| "OAuth access token has expired for this connection" | ||
| ) | ||
|
|
||
| def test_case_insensitive(self) -> None: | ||
| assert _is_platform_credential_error("sso AUTHENTICATION Has Expired") | ||
|
|
||
| def test_does_not_match_generic_query_error(self) -> None: | ||
| assert not _is_platform_credential_error("column 'revenue' not found in table") | ||
|
|
||
| def test_does_not_match_syntax_error(self) -> None: | ||
| assert not _is_platform_credential_error( | ||
| "SQL compilation error: syntax error at position 42" | ||
| ) | ||
|
|
||
| def test_does_not_match_timeout_error(self) -> None: | ||
| assert not _is_platform_credential_error("Query timed out after 60 seconds") | ||
|
|
||
| def test_does_not_match_empty_string(self) -> None: | ||
| assert not _is_platform_credential_error("") | ||
|
|
||
|
|
||
| class TestFormatSemanticLayerErrorWithCredentialHint: | ||
| """Tests that _format_semantic_layer_error appends the credential hint.""" | ||
|
|
||
| def test_sso_expired_includes_platform_hint(self, fetcher) -> None: | ||
| error = Exception( | ||
| "SSO authentication has expired, please re-connect to Snowflake: " | ||
| "https://docs.getdbt.com/faqs/Troubleshooting/refresh-snowflake-oauth-credentials" | ||
| ) | ||
| result = fetcher._format_semantic_layer_error(error) | ||
| assert "dbt Cloud" in result | ||
| assert "Profile → Credentials" in result | ||
| assert "not a local authentication problem" in result | ||
|
|
||
| def test_sso_expired_preserves_original_message(self, fetcher) -> None: | ||
| error = Exception( | ||
| "SSO authentication has expired, please re-connect to Snowflake" | ||
| ) | ||
| result = fetcher._format_semantic_layer_error(error) | ||
| assert "SSO authentication has expired" in result | ||
|
|
||
| def test_generic_error_does_not_include_platform_hint(self, fetcher) -> None: | ||
| error = Exception("column 'revenue' not found") | ||
| result = fetcher._format_semantic_layer_error(error) | ||
| assert _PLATFORM_CREDENTIAL_HINT not in result | ||
| assert "dbt Cloud UI" not in result | ||
|
|
||
| def test_query_failed_error_with_credential_message_includes_hint( | ||
| self, fetcher | ||
| ) -> None: | ||
| """QueryFailedError wrapping a credential expiry should also get the hint.""" | ||
| error = Exception( | ||
| 'QueryFailedError(["SSO authentication has expired, ' | ||
| 'please re-connect to Snowflake"])' | ||
| ) | ||
| result = fetcher._format_semantic_layer_error(error) | ||
| assert "dbt Cloud" in result | ||
| assert "Profile → Credentials" in result | ||
|
|
||
| def test_format_query_failed_error_with_credential_message(self, fetcher) -> None: | ||
| """_format_query_failed_error should also include the hint for credential errors.""" | ||
| from dbtsl.error import QueryFailedError | ||
|
|
||
| error = QueryFailedError( | ||
| message="SSO authentication has expired, please re-connect to Snowflake", | ||
| status="FAILED", | ||
| ) | ||
| result = fetcher._format_query_failed_error(error) | ||
| assert "dbt Cloud" in result.error | ||
| assert "Profile → Credentials" in result.error |
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left a comment related to these lines in the issue. Let me know what you think! We can continue that convo there for now.