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/09/25 16:40:33 UTC
(superset) 01/01: fix(database): catch JSONDecodeError in get_oauth2_config
This is an automated email from the ASF dual-hosted git repository.
eschutho pushed a commit to branch fix-oauth2-config-encrypted-extra-decode-error
in repository https://gitbox.apache.org/repos/asf/superset.git
commit d09a7803af731dde264ba094c39b6f8094f86fd6
Author: Elizabeth Thompson <es...@gmail.com>
AuthorDate: Fri Sep 25 16:40:15 2026 +0000
fix(database): catch JSONDecodeError in get_oauth2_config
Database.get_oauth2_config() calls json.loads(self.encrypted_extra)
without any exception handling. If encrypted_extra contains malformed
JSON (hand-edited config, partial write, migration artifact), a raw
simplejson.JSONDecodeError (a ValueError, not a SupersetException)
escapes through _get_sqla_engine on every connection attempt.
Wrap the json.loads call in a try/except and raise
SupersetGenericDBErrorException instead, matching the fix pattern
from PR #44616.
Co-Authored-By: Claude Opus 4.6 <no...@anthropic.com>
---
superset/models/core.py | 7 ++++++-
tests/unit_tests/models/core_test.py | 21 ++++++++++++++++++++-
2 files changed, 26 insertions(+), 2 deletions(-)
diff --git a/superset/models/core.py b/superset/models/core.py
index 5712a306f6a..ef5a7109cd2 100755
--- a/superset/models/core.py
+++ b/superset/models/core.py
@@ -69,6 +69,7 @@ from superset.constants import LRU_CACHE_MAX_SIZE, PASSWORD_MASK
from superset.databases.error_provenance import mark_database_engine_error
from superset.databases.utils import make_url_safe
from superset.db_engine_specs.base import MetricType, TimeGrain
+from superset.exceptions import SupersetGenericDBErrorException
from superset.extensions import (
cache_manager,
encrypted_field_factory,
@@ -1508,7 +1509,11 @@ class Database(CoreDatabase, AuditMixinNullable, ImportExportMixin): # pylint:
admins to create custom OAuth2 clients from the Superset UI, and assign them to
specific databases.
"""
- encrypted_extra = json.loads(self.encrypted_extra or "{}")
+ try:
+ encrypted_extra = json.loads(self.encrypted_extra or "{}")
+ except json.JSONDecodeError as ex:
+ logger.error(ex, exc_info=True)
+ raise SupersetGenericDBErrorException(message=str(ex)) from ex
if oauth2_client_info := encrypted_extra.get("oauth2_client_info"):
schema = OAuth2ClientConfigSchema()
client_config = schema.load(oauth2_client_info)
diff --git a/tests/unit_tests/models/core_test.py b/tests/unit_tests/models/core_test.py
index c614e44f401..94fb6254605 100644
--- a/tests/unit_tests/models/core_test.py
+++ b/tests/unit_tests/models/core_test.py
@@ -40,7 +40,11 @@ from sqlalchemy.sql import Select
from superset.connectors.sqla.models import SqlaTable, TableColumn
from superset.databases.error_provenance import mark_database_engine_error
from superset.errors import SupersetErrorType
-from superset.exceptions import OAuth2Error, OAuth2RedirectError
+from superset.exceptions import (
+ OAuth2Error,
+ OAuth2RedirectError,
+ SupersetGenericDBErrorException,
+)
from superset.models.core import Database
from superset.sql.parse import LimitMethod, Table
from superset.utils import json
@@ -1247,6 +1251,21 @@ def test_get_oauth2_config_redirect_uri_from_config(
assert config["redirect_uri"] == custom_redirect_uri
+def test_get_oauth2_config_malformed_encrypted_extra(app_context: None) -> None:
+ """
+ Test that malformed JSON in ``encrypted_extra`` raises a Superset exception
+ instead of leaking the raw ``JSONDecodeError``.
+ """
+ database = Database(
+ database_name="db",
+ sqlalchemy_uri="postgresql://user:password@host:5432/examples",
+ )
+ database.encrypted_extra = "{not valid json"
+
+ with pytest.raises(SupersetGenericDBErrorException):
+ database.get_oauth2_config()
+
+
def test_raw_connection_oauth_engine(mocker: MockerFixture) -> None:
"""
Test that we can start OAuth2 from `raw_connection()` errors.