This is an automated email from the ASF dual-hosted git repository.

eschutho pushed a commit to branch fix-extra-params-encrypted-extra-decode-error
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 36f620867a426ce1908d7ad6e6e409c934173a3b
Author: Elizabeth Thompson <[email protected]>
AuthorDate: Thu Sep 24 16:47:57 2026 +0000

    fix(db_engine_specs): raise SupersetGenericDBErrorException instead of 
bare-reraising JSONDecodeError
    
    BaseEngineSpec.get_extra_params and update_params_from_encrypted_extra
    caught json.JSONDecodeError on malformed `extra` / `encrypted_extra`,
    logged it, and re-raised the raw simplejson exception. Wrap it in a
    SupersetGenericDBErrorException so callers that handle SupersetException
    return a typed error instead of an opaque 500.
    
    Co-Authored-By: Claude Opus 5.5 <[email protected]>
---
 superset/db_engine_specs/base.py              |  5 ++--
 tests/unit_tests/db_engine_specs/test_base.py | 33 ++++++++++++++++++++++++++-
 2 files changed, 35 insertions(+), 3 deletions(-)

diff --git a/superset/db_engine_specs/base.py b/superset/db_engine_specs/base.py
index a32aeb9f34d..2c253c66642 100644
--- a/superset/db_engine_specs/base.py
+++ b/superset/db_engine_specs/base.py
@@ -71,6 +71,7 @@ from superset.exceptions import (
     OAuth2Error,
     OAuth2RedirectError,
     OAuth2TokenRefreshError,
+    SupersetGenericDBErrorException,
     SupersetParseError,
 )
 from superset.key_value.types import JsonKeyValueCodec, KeyValueResource
@@ -2727,7 +2728,7 @@ class BaseEngineSpec:  # pylint: 
disable=too-many-public-methods
                 extra = json.loads(database.extra)
             except json.JSONDecodeError as ex:
                 logger.error(ex, exc_info=True)
-                raise
+                raise SupersetGenericDBErrorException(message=str(ex)) from ex
         return extra
 
     @staticmethod
@@ -2748,7 +2749,7 @@ class BaseEngineSpec:  # pylint: 
disable=too-many-public-methods
             params.update(encrypted_extra)
         except json.JSONDecodeError as ex:
             logger.error(ex, exc_info=True)
-            raise
+            raise SupersetGenericDBErrorException(message=str(ex)) from ex
 
     @classmethod
     def array_contains_any(cls, col: ColumnElement, values: list[Any]) -> 
ColumnElement:
diff --git a/tests/unit_tests/db_engine_specs/test_base.py 
b/tests/unit_tests/db_engine_specs/test_base.py
index 3bb258fb199..63d61c5f4c3 100644
--- a/tests/unit_tests/db_engine_specs/test_base.py
+++ b/tests/unit_tests/db_engine_specs/test_base.py
@@ -39,7 +39,11 @@ from superset.db_engine_specs.base import (
     convert_inspector_columns,
 )
 from superset.errors import ErrorLevel, SupersetError, SupersetErrorType
-from superset.exceptions import OAuth2Error, OAuth2RedirectError
+from superset.exceptions import (
+    OAuth2Error,
+    OAuth2RedirectError,
+    SupersetGenericDBErrorException,
+)
 from superset.sql.parse import Table
 from superset.superset_typing import (
     OAuth2ClientConfig,
@@ -345,6 +349,33 @@ def test_quote_table() -> None:
     )
 
 
+def test_get_extra_params_malformed_json(mocker: MockerFixture) -> None:
+    """
+    Test that malformed JSON in `extra` raises a Superset exception instead of
+    leaking the raw `JSONDecodeError`.
+    """
+    database = mocker.MagicMock(extra="{not valid json")
+
+    with pytest.raises(SupersetGenericDBErrorException):
+        BaseEngineSpec.get_extra_params(database)
+
+
+def test_update_params_from_encrypted_extra_malformed_json(
+    mocker: MockerFixture,
+) -> None:
+    """
+    Test that malformed JSON in `encrypted_extra` raises a Superset exception
+    instead of leaking the raw `JSONDecodeError`.
+    """
+    database = mocker.MagicMock(encrypted_extra="{not valid json")
+    params: dict[str, Any] = {}
+
+    with pytest.raises(SupersetGenericDBErrorException):
+        BaseEngineSpec.update_params_from_encrypted_extra(database, params)
+
+    assert params == {}
+
+
 def test_mask_encrypted_extra() -> None:
     """
     Test that the private key is masked when the database is edited.

Reply via email to