fix(dashboard): catch DatasourceNotFound in get_datasets to prevent 404 (#37503)

This commit is contained in:
Gabriel Torres Ruiz
2026-01-28 20:54:56 -03:00
committed by GitHub
parent bb5be6cf54
commit 06e4f4ff4c
2 changed files with 48 additions and 1 deletions

View File

@@ -76,6 +76,7 @@ from superset.connectors.sqla.utils import (
get_physical_table_metadata,
get_virtual_table_metadata,
)
from superset.daos.exceptions import DatasourceNotFound
from superset.db_engine_specs.base import BaseEngineSpec, TimestampExpression
from superset.exceptions import (
ColumnNotFoundException,
@@ -513,7 +514,13 @@ class BaseDatasource(
# for legacy dashboard imports which have the wrong query_context in them
try:
query_context = slc.get_query_context()
except DatasetNotFoundError:
except (DatasetNotFoundError, DatasourceNotFound):
logger.warning(
"Failed to load query_context for chart '%s' (id=%s): "
"referenced datasource not found",
slc.slice_name,
slc.id,
)
query_context = None
# legacy charts don't have query_context charts

View File

@@ -24,6 +24,7 @@ from sqlalchemy.orm.session import Session
from superset.connectors.sqla.models import SqlaTable, TableColumn
from superset.daos.dataset import DatasetDAO
from superset.daos.exceptions import DatasourceNotFound
from superset.exceptions import OAuth2RedirectError
from superset.models.core import Database
from superset.sql.parse import Table
@@ -906,3 +907,42 @@ def test_sqla_table_link_escapes_url(mocker: MockerFixture) -> None:
# Verify that special characters are escaped in both name and URL
assert "<script>" in str(link)
assert "<script>" not in str(link)
def test_data_for_slices_handles_missing_datasource(mocker: MockerFixture) -> None:
"""
Test that data_for_slices gracefully handles a chart whose query_context
references a datasource that no longer exists.
When a chart's query_context references a deleted datasource, get_query_context()
raises DatasourceNotFound. The fix ensures this exception is caught and logged,
allowing the dashboard to load normally instead of returning a 404.
"""
database = mocker.MagicMock()
database.id = 1
table = SqlaTable(
table_name="test_table",
database=database,
columns=[],
metrics=[],
)
# Create a mock slice whose get_query_context raises DatasourceNotFound
mock_slice = mocker.MagicMock()
mock_slice.id = 1
mock_slice.slice_name = "Test Chart"
mock_slice.form_data = {}
mock_slice.get_query_context.side_effect = DatasourceNotFound()
# Mock the columns and metrics properties to return empty lists
mocker.patch.object(SqlaTable, "columns", [])
mocker.patch.object(SqlaTable, "metrics", [])
# This should not raise an exception - the fix catches DatasourceNotFound
result = table.data_for_slices([mock_slice])
# Verify the method returns a valid data structure
assert "columns" in result
assert "metrics" in result
assert "verbose_map" in result