fix: Better error message for dashboard import (#7621)
Common mistake is trying to import dashboard without creating
datasources first. Currently it causes error 500 with a message
> sqlalchemy.orm.exc.NoResultFound: No row was found for one()
which is difficult to understand.
This commit catches NoResultFound error and returns human readable error
using flash('danger').
Ref: #2992
This commit is contained in:
parent
9b8996038e
commit
2fa071a3ac
|
|
@ -42,6 +42,7 @@ from sqlalchemy import (
|
|||
)
|
||||
from sqlalchemy.exc import CompileError
|
||||
from sqlalchemy.orm import backref, relationship
|
||||
from sqlalchemy.orm.exc import NoResultFound
|
||||
from sqlalchemy.schema import UniqueConstraint
|
||||
from sqlalchemy.sql import column, literal_column, table, text
|
||||
from sqlalchemy.sql.expression import Label, TextAsFrom
|
||||
|
|
@ -50,6 +51,7 @@ import sqlparse
|
|||
from superset import app, db, security_manager
|
||||
from superset.connectors.base.models import BaseColumn, BaseDatasource, BaseMetric
|
||||
from superset.db_engine_specs.base import TimestampExpression
|
||||
from superset.exceptions import DatabaseNotFound
|
||||
from superset.jinja_context import get_template_processor
|
||||
from superset.models.annotations import Annotation
|
||||
from superset.models.core import Database
|
||||
|
|
@ -1005,11 +1007,19 @@ class SqlaTable(Model, BaseDatasource):
|
|||
)
|
||||
|
||||
def lookup_database(table):
|
||||
return (
|
||||
db.session.query(Database)
|
||||
.filter_by(database_name=table.params_dict["database_name"])
|
||||
.one()
|
||||
)
|
||||
try:
|
||||
return (
|
||||
db.session.query(Database)
|
||||
.filter_by(database_name=table.params_dict["database_name"])
|
||||
.one()
|
||||
)
|
||||
except NoResultFound:
|
||||
raise DatabaseNotFound(
|
||||
_(
|
||||
"Database '%(name)s' is not found",
|
||||
name=table.params_dict["database_name"],
|
||||
)
|
||||
)
|
||||
|
||||
return import_datasource.import_datasource(
|
||||
db.session, i_datasource, lookup_database, lookup_sqlatable, import_time
|
||||
|
|
|
|||
|
|
@ -54,3 +54,7 @@ class SupersetTemplateException(SupersetException):
|
|||
|
||||
class SpatialException(SupersetException):
|
||||
pass
|
||||
|
||||
|
||||
class DatabaseNotFound(SupersetException):
|
||||
status = 400
|
||||
|
|
|
|||
|
|
@ -64,7 +64,11 @@ from superset import (
|
|||
)
|
||||
from superset.connectors.connector_registry import ConnectorRegistry
|
||||
from superset.connectors.sqla.models import AnnotationDatasource, SqlaTable
|
||||
from superset.exceptions import SupersetException, SupersetSecurityException
|
||||
from superset.exceptions import (
|
||||
DatabaseNotFound,
|
||||
SupersetException,
|
||||
SupersetSecurityException,
|
||||
)
|
||||
from superset.forms import CsvToDatabaseForm
|
||||
from superset.jinja_context import get_template_processor
|
||||
from superset.legacy import update_time_range
|
||||
|
|
@ -1441,7 +1445,26 @@ class Superset(BaseSupersetView):
|
|||
"""Overrides the dashboards using json instances from the file."""
|
||||
f = request.files.get("file")
|
||||
if request.method == "POST" and f:
|
||||
dashboard_import_export.import_dashboards(db.session, f.stream)
|
||||
try:
|
||||
dashboard_import_export.import_dashboards(db.session, f.stream)
|
||||
except DatabaseNotFound as e:
|
||||
flash(
|
||||
_(
|
||||
"Cannot import dashboard: %(db_error)s.\n"
|
||||
"Make sure to create the database before "
|
||||
"importing the dashboard.",
|
||||
db_error=e,
|
||||
),
|
||||
"danger",
|
||||
)
|
||||
except Exception:
|
||||
flash(
|
||||
_(
|
||||
"An unknown error occurred. "
|
||||
"Please contact your Superset administrator"
|
||||
),
|
||||
"danger",
|
||||
)
|
||||
return redirect("/dashboard/list/")
|
||||
return self.render_template("superset/import_dashboards.html")
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue