(
updateState({
resource: json.result,
});
+ return json.result;
},
createErrorHandler(errMsg =>
handleErrorMsg(
diff --git a/superset/databases/schemas.py b/superset/databases/schemas.py
index 4bcca21531..e0f7242a9f 100644
--- a/superset/databases/schemas.py
+++ b/superset/databases/schemas.py
@@ -131,15 +131,12 @@ def sqlalchemy_uri_validator(value: str) -> str:
"""
try:
make_url(value.strip())
- except (ArgumentError, AttributeError):
+ except (ArgumentError, AttributeError, ValueError):
raise ValidationError(
[
_(
- "Invalid connection string, a valid string usually follows:"
- "'DRIVER://USER:PASSWORD@DB-HOST/DATABASE-NAME'"
- ""
- "Example:'postgresql://user:password@your-postgres-db/database'"
- "
"
+ "Invalid connection string, a valid string usually follows: "
+ "dirver://user:password@database-host/database-name"
)
]
)
diff --git a/superset/models/core.py b/superset/models/core.py
index 952ba83bba..382239209f 100755
--- a/superset/models/core.py
+++ b/superset/models/core.py
@@ -46,6 +46,7 @@ from sqlalchemy import (
from sqlalchemy.engine import Dialect, Engine, url
from sqlalchemy.engine.reflection import Inspector
from sqlalchemy.engine.url import make_url, URL
+from sqlalchemy.exc import ArgumentError
from sqlalchemy.ext.hybrid import hybrid_property
from sqlalchemy.orm import relationship
from sqlalchemy.pool import NullPool
@@ -646,7 +647,12 @@ class Database(
@property
def sqlalchemy_uri_decrypted(self) -> str:
- conn = sqla.engine.url.make_url(self.sqlalchemy_uri)
+ try:
+ conn = sqla.engine.url.make_url(self.sqlalchemy_uri)
+ except (ArgumentError, ValueError):
+ # if the URI is invalid, ignore and return a placeholder url
+ # (so users see 500 less often)
+ return "dialect://invalid_uri"
if custom_password_store:
conn.password = custom_password_store(conn)
else:
diff --git a/tests/databases/api_tests.py b/tests/databases/api_tests.py
index 4d3d5ce62e..8e8d0930b2 100644
--- a/tests/databases/api_tests.py
+++ b/tests/databases/api_tests.py
@@ -289,17 +289,9 @@ class TestDatabaseApi(SupersetTestCase):
rv = self.client.post(uri, json=database_data)
response = json.loads(rv.data.decode("utf-8"))
self.assertEqual(rv.status_code, 400)
- expected_response = {
- "message": {
- "sqlalchemy_uri": [
- "Invalid connection string, a valid string usually "
- "follows:'DRIVER://USER:PASSWORD@DB-HOST/DATABASE-NAME'"
- "Example:'postgresql://user:password@your-postgres-db/database'"
- "
"
- ]
- }
- }
- self.assertEqual(response, expected_response)
+ self.assertIn(
+ "Invalid connection string", response["message"]["sqlalchemy_uri"][0],
+ )
def test_create_database_fail_sqllite(self):
"""
@@ -447,17 +439,9 @@ class TestDatabaseApi(SupersetTestCase):
rv = self.client.put(uri, json=database_data)
response = json.loads(rv.data.decode("utf-8"))
self.assertEqual(rv.status_code, 400)
- expected_response = {
- "message": {
- "sqlalchemy_uri": [
- "Invalid connection string, a valid string usually "
- "follows:'DRIVER://USER:PASSWORD@DB-HOST/DATABASE-NAME'"
- "Example:'postgresql://user:password@your-postgres-db/database'"
- "
"
- ]
- }
- }
- self.assertEqual(response, expected_response)
+ self.assertIn(
+ "Invalid connection string", response["message"]["sqlalchemy_uri"][0],
+ )
def test_delete_database(self):
"""