You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by el...@apache.org on 2026/08/06 22:05:14 UTC
(superset) branch master updated: fix(datasets): catch TemplateError instead of narrower TemplateSyntaxError in render_dataset_fields (#42802)
This is an automated email from the ASF dual-hosted git repository.
eschutho pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git
The following commit(s) were added to refs/heads/master by this push:
new 7dd6ce835f5 fix(datasets): catch TemplateError instead of narrower TemplateSyntaxError in render_dataset_fields (#42802)
7dd6ce835f5 is described below
commit 7dd6ce835f5652d790fd8fc5c1900680f050365b
Author: Elizabeth Thompson <es...@gmail.com>
AuthorDate: Thu Aug 6 15:05:08 2026 -0700
fix(datasets): catch TemplateError instead of narrower TemplateSyntaxError in render_dataset_fields (#42802)
---
superset/datasets/api.py | 4 +--
tests/unit_tests/datasets/api_tests.py | 51 ++++++++++++++++++++++++++++++++++
2 files changed, 53 insertions(+), 2 deletions(-)
diff --git a/superset/datasets/api.py b/superset/datasets/api.py
index a35e22345ae..1fc7634b8b3 100644
--- a/superset/datasets/api.py
+++ b/superset/datasets/api.py
@@ -30,7 +30,7 @@ from flask_appbuilder.api.schemas import get_item_schema
from flask_appbuilder.const import API_RESULT_RES_KEY, API_SELECT_COLUMNS_RIS_KEY
from flask_appbuilder.models.sqla.interface import SQLAInterface
from flask_babel import ngettext
-from jinja2.exceptions import TemplateSyntaxError
+from jinja2.exceptions import TemplateError
from marshmallow import ValidationError
from sqlalchemy.orm.exc import MultipleResultsFound
@@ -1835,7 +1835,7 @@ class DatasetRestApi(SoftDeleteApiMixin, BaseSupersetModelRestApi):
try:
data[new_key] = func(data[key])
- except (TemplateSyntaxError, SupersetSyntaxErrorException) as ex:
+ except (TemplateError, SupersetSyntaxErrorException) as ex:
template_exception = SupersetTemplateException(
f"Unable to render expression from dataset {item_type}.",
)
diff --git a/tests/unit_tests/datasets/api_tests.py b/tests/unit_tests/datasets/api_tests.py
index c536fad9ea5..c2d4b0711cf 100644
--- a/tests/unit_tests/datasets/api_tests.py
+++ b/tests/unit_tests/datasets/api_tests.py
@@ -122,6 +122,57 @@ def test_get_dataset_include_rendered_sql_passes_table_to_template_processor(
mock_get_processor.assert_called_once_with(database=database, table=dataset)
+def test_get_dataset_include_rendered_sql_handles_undefined_error(
+ session: Session,
+ client: Any,
+ full_api_access: None,
+) -> None:
+ """
+ Dataset API: Test that include_rendered_sql returns a typed 422 instead
+ of an unhandled 500 when the template processor raises a raw
+ ``jinja2.exceptions.UndefinedError``.
+
+ Regression test for the bug where an undefined variable accessed via
+ attribute/subscript (e.g. ``{{ foo.bar }}``) raises ``UndefinedError``
+ from ``process_template``, which is not a subclass of
+ ``TemplateSyntaxError`` and so escaped ``render_dataset_fields``'s
+ exception handling unhandled.
+ """
+ from jinja2.exceptions import UndefinedError
+
+ from superset.connectors.sqla.models import SqlaTable
+ from superset.models.core import Database
+
+ SqlaTable.metadata.create_all(db.session.get_bind())
+
+ database = Database(
+ database_name="my_db",
+ sqlalchemy_uri="sqlite://",
+ )
+ dataset = SqlaTable(
+ table_name="test_render_sql_undefined_table",
+ schema="my_schema",
+ database=database,
+ sql="SELECT 1",
+ )
+ db.session.add(dataset)
+ db.session.flush()
+
+ mock_processor = MagicMock()
+ mock_processor.process_template.side_effect = UndefinedError("'foo' is undefined")
+
+ with patch(
+ "superset.datasets.api.get_template_processor",
+ return_value=mock_processor,
+ ):
+ response = client.get(
+ f"/api/v1/dataset/{dataset.id}?include_rendered_sql=true",
+ )
+
+ assert response.status_code == 422
+ assert "Unable to render expression from dataset" in response.json["message"]
+
+
def test_handle_filters_args_returns_request_scoped_filters(
session: Session,
client: Any,