From 591857f7ad32c89cf3b1a5ed823f8df631071441 Mon Sep 17 00:00:00 2001 From: Norman Hooper Date: Tue, 5 Dec 2023 16:17:33 +0000 Subject: [PATCH] Error handling in DataSetChangeAPI view --- hq_superset/utils.py | 12 ++++++++++-- hq_superset/views.py | 21 ++++++++++++++++----- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/hq_superset/utils.py b/hq_superset/utils.py index 80bf918..8a2b5b3 100644 --- a/hq_superset/utils.py +++ b/hq_superset/utils.py @@ -40,8 +40,16 @@ def get_hq_database(): from superset import db from superset.models.core import Database - # Todo; get actual DB once that's implemented - return db.session.query(Database).filter_by(database_name=HQ_DB_CONNECTION_NAME).one() + try: + hq_db = ( + db.session + .query(Database) + .filter_by(database_name=HQ_DB_CONNECTION_NAME) + .one() + ) + except sqlalchemy.orm.exc.NoResultFound as err: + raise CCHQApiException('CommCare HQ database missing') from err + return hq_db def get_schema_name_for_domain(domain): diff --git a/hq_superset/views.py b/hq_superset/views.py index 9898cb1..2b63562 100644 --- a/hq_superset/views.py +++ b/hq_superset/views.py @@ -6,6 +6,7 @@ import superset from flask import Response, abort, flash, g, redirect, request, url_for from flask_appbuilder import expose +from flask_appbuilder.baseviews import expose_api from flask_appbuilder.security.decorators import has_access, permission_name from superset import db from superset.connectors.sqla.models import SqlaTable @@ -15,8 +16,13 @@ DatasetForbiddenError, DatasetNotFoundError, ) +from superset.extensions import csrf from superset.superset_typing import FlaskResponse -from superset.views.base import BaseSupersetView, json_error_response +from superset.views.base import ( + BaseSupersetView, + handle_api_exception, + json_error_response, +) from .hq_domain import user_domains from .models import DataSetChange @@ -217,10 +223,11 @@ class DataSetChangeAPI(BaseSupersetView): def __init__(self): self.route_base = '/hq_webhook' - self.default_view = 'post' + self.default_view = 'post_dataset_change' super().__init__() - @expose('/change/', methods=['POST']) + # http://localhost:8088/hq_webhook/change/ + @expose_api(url='/change/', methods=('POST',)) # TODO: Authenticate # e.g. superset.views.datasource.views.Datasource: # @event_logger.log_this_with_context( @@ -229,8 +236,9 @@ def __init__(self): # ) # @has_access_api # @api - # @handle_api_exception - def post(self) -> FlaskResponse: + @handle_api_exception + @csrf.exempt + def post_dataset_change(self) -> FlaskResponse: if request.content_length > self.MAX_REQUEST_LENGTH: return json_error_response( HTTPStatus.REQUEST_ENTITY_TOO_LARGE.description, @@ -255,3 +263,6 @@ def post(self) -> FlaskResponse: str(err), status=HTTPStatus.BAD_REQUEST.value, ) + # `@handle_api_exception` will return other exceptions as JSON + # with status code 500, e.g. + # {"error": "CommCare HQ database missing"}