From commits-return-2893-archive-asf-public=cust-asf.ponee.io@superset.incubator.apache.org Thu Jul 4 04:52:13 2019 Return-Path: X-Original-To: archive-asf-public@cust-asf.ponee.io Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [207.244.88.153]) by mx-eu-01.ponee.io (Postfix) with SMTP id 2A7A6180181 for ; Thu, 4 Jul 2019 06:52:13 +0200 (CEST) Received: (qmail 43784 invoked by uid 500); 4 Jul 2019 04:52:12 -0000 Mailing-List: contact commits-help@superset.incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@superset.incubator.apache.org Delivered-To: mailing list commits@superset.incubator.apache.org Received: (qmail 43775 invoked by uid 99); 4 Jul 2019 04:52:12 -0000 Received: from ec2-52-202-80-70.compute-1.amazonaws.com (HELO gitbox.apache.org) (52.202.80.70) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 04 Jul 2019 04:52:12 +0000 Received: by gitbox.apache.org (ASF Mail Server at gitbox.apache.org, from userid 33) id 3136987AD7; Thu, 4 Jul 2019 04:52:12 +0000 (UTC) Date: Thu, 04 Jul 2019 04:52:11 +0000 To: "commits@superset.apache.org" Subject: [incubator-superset] branch master updated: fix: Better error message for dashboard import (#7621) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Message-ID: <156221593153.16242.17330213425811874793@gitbox.apache.org> From: maximebeauchemin@apache.org X-Git-Host: gitbox.apache.org X-Git-Repo: incubator-superset X-Git-Refname: refs/heads/master X-Git-Reftype: branch X-Git-Oldrev: 9b8996038e0ff02f8902cdb8e1822d8000f79210 X-Git-Newrev: 2fa071a3ac1a67a80be64b4a8ee5bb5ee7a207ba X-Git-Rev: 2fa071a3ac1a67a80be64b4a8ee5bb5ee7a207ba X-Git-NotificationType: ref_changed_plus_diff X-Git-Multimail-Version: 1.5.dev Auto-Submitted: auto-generated This is an automated email from the ASF dual-hosted git repository. maximebeauchemin pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-superset.git The following commit(s) were added to refs/heads/master by this push: new 2fa071a fix: Better error message for dashboard import (#7621) 2fa071a is described below commit 2fa071a3ac1a67a80be64b4a8ee5bb5ee7a207ba Author: Maxim Sukharev AuthorDate: Thu Jul 4 06:52:00 2019 +0200 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 --- superset/connectors/sqla/models.py | 20 +++++++++++++++----- superset/exceptions.py | 4 ++++ superset/views/core.py | 27 +++++++++++++++++++++++++-- 3 files changed, 44 insertions(+), 7 deletions(-) diff --git a/superset/connectors/sqla/models.py b/superset/connectors/sqla/models.py index 40eb25e..6805777 100644 --- a/superset/connectors/sqla/models.py +++ b/superset/connectors/sqla/models.py @@ -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 diff --git a/superset/exceptions.py b/superset/exceptions.py index ae491fc..ade6ef8 100644 --- a/superset/exceptions.py +++ b/superset/exceptions.py @@ -54,3 +54,7 @@ class SupersetTemplateException(SupersetException): class SpatialException(SupersetException): pass + + +class DatabaseNotFound(SupersetException): + status = 400 diff --git a/superset/views/core.py b/superset/views/core.py index 6d18176..5cedfe1 100755 --- a/superset/views/core.py +++ b/superset/views/core.py @@ -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")