Return 404 when the dataset does not exist (#1581)

Also in this PR, restructure the exception handling.

fixes #1566
This commit is contained in:
bmccandless
2020-06-23 17:14:42 -07:00
committed by GitHub
parent 9e7ecfa279
commit e22e671f10
3 changed files with 57 additions and 58 deletions
+10 -5
View File
@@ -9,7 +9,7 @@ from server_timing import Timing as ServerTiming
from http import HTTPStatus from http import HTTPStatus
import server.common.rest as common_rest import server.common.rest as common_rest
from server.common.errors import DatasetAccessError from server.common.errors import DatasetAccessError, RequestException
from server.common.utils import path_join, Float32JSONEncoder from server.common.utils import path_join, Float32JSONEncoder
from server.common.data_locator import DataLocator from server.common.data_locator import DataLocator
from server.common.health import health_check from server.common.health import health_check
@@ -81,9 +81,9 @@ def dataset_index(url_dataroot=None, dataset=None):
return render_template( return render_template(
"index.html", datasetTitle=dataset_title, SCRIPTS=scripts, INLINE_SCRIPTS=inline_scripts "index.html", datasetTitle=dataset_title, SCRIPTS=scripts, INLINE_SCRIPTS=inline_scripts
) )
except DatasetAccessError: except DatasetAccessError as e:
return common_rest.abort_and_log( return common_rest.abort_and_log(
HTTPStatus.BAD_REQUEST, f"Invalid dataset {dataset}", loglevel=logging.INFO, include_exc_info=True e.status_code, f"Invalid dataset {dataset}: {e.message}", loglevel=logging.INFO, include_exc_info=True
) )
@@ -94,6 +94,11 @@ def health():
return health_check(config) return health_check(config)
@webbp.errorhandler(RequestException)
def handle_request_exception(error):
return common_rest.abort_and_log(error.status_code, error.message, loglevel=logging.INFO, include_exc_info=True)
def get_data_adaptor(url_dataroot=None, dataset=None): def get_data_adaptor(url_dataroot=None, dataset=None):
config = current_app.app_config config = current_app.app_config
@@ -123,9 +128,9 @@ def rest_get_data_adaptor(func):
try: try:
with get_data_adaptor(self.url_dataroot, dataset) as data_adaptor: with get_data_adaptor(self.url_dataroot, dataset) as data_adaptor:
return func(self, data_adaptor) return func(self, data_adaptor)
except DatasetAccessError: except DatasetAccessError as e:
return common_rest.abort_and_log( return common_rest.abort_and_log(
HTTPStatus.BAD_REQUEST, f"Invalid dataset {dataset}", loglevel=logging.INFO, include_exc_info=True e.status_code, f"Invalid dataset {dataset}: {e.message}", loglevel=logging.INFO, include_exc_info=True
) )
return wrapped_function return wrapped_function
+45 -52
View File
@@ -1,92 +1,85 @@
class FilterError(Exception): from http import HTTPStatus
"""
Raised when filter is malformed
""" class RequestException(Exception):
"""Baseclass for exceptions that can be raised from a request."""
# The default status code is 400 (Bad Request)
default_status_code = HTTPStatus.BAD_REQUEST
def __init__(self, message, status_code=None):
Exception.__init__(self)
self.message = message
self.status_code = status_code or self.default_status_code
class FilterError(RequestException):
"""Raised when filter is malformed"""
pass pass
class JSONEncodingValueError(Exception): class JSONEncodingValueError(RequestException):
""" """Raised when data cannot be encoded into json"""
Raised when data cannot be encoded into json
"""
pass pass
class MimeTypeError(Exception): class MimeTypeError(RequestException):
""" """Raised when incompatible MIME type selected"""
Raised when incompatible MIME type selected
"""
pass pass
class PrepareError(Exception): class DatasetAccessError(RequestException):
""" """Raised when file loaded into a DataAdaptor is misformatted"""
Raised when data is misprepared
"""
pass pass
class DatasetAccessError(Exception): class DisabledFeatureError(RequestException):
""" """Raised when an attempt to use a disabled feature occurs"""
Raised when file loaded into a DataAdaptor is misformatted
"""
pass pass
class DisabledFeatureError(Exception): class AnnotationsError(RequestException):
""" """Raised when an attempt to use the annotations feature fails"""
Raised when an attempt to use a disabled feature occurs
"""
pass pass
class AnnotationsError(Exception): class ComputeError(RequestException):
""" """Raised when an error occurs during a compute algorithm (such as diffexp)"""
Raised when an attempt to use the annotations feature fails
""" default_status_code = HTTPStatus.INTERNAL_SERVER_ERROR
class ExceedsLimitError(RequestException):
"""Raised when an HTTP request exceeds a limit/quota"""
pass
class ColorFormatException(RequestException):
"""Raised when color helper functions encounter an unknown color format"""
pass pass
class OntologyLoadFailure(Exception): class OntologyLoadFailure(Exception):
""" """Raised when reading the ontology file fails"""
Raised when reading the ontology file fails
"""
pass pass
class ConfigurationError(Exception): class ConfigurationError(Exception):
""" """Raised when checking configuration errors"""
Raised when checking configuration errors
"""
pass pass
class ExceedsLimitError(Exception): class PrepareError(Exception):
""" """Raised when data is misprepared"""
Raised when an HTTP request exceeds a limit/quota
"""
pass
class ComputeError(Exception):
"""
Raised when an error occurs during a compute algorithm (such as diffexp)
"""
pass
class ColorFormatException(Exception):
"""Raised when color helper functions encounter an unknown color format"""
pass pass
+2 -1
View File
@@ -5,6 +5,7 @@ from server.data_common.rwlock import RWLock
from server.common.errors import DatasetAccessError from server.common.errors import DatasetAccessError
from server.common.data_locator import DataLocator from server.common.data_locator import DataLocator
from contextlib import contextmanager from contextlib import contextmanager
from http import HTTPStatus
class MatrixDataCacheItem(object): class MatrixDataCacheItem(object):
@@ -217,7 +218,7 @@ class MatrixDataLoader(object):
region_name = None if app_config is None else app_config.data_locator__s3__region_name region_name = None if app_config is None else app_config.data_locator__s3__region_name
self.location = DataLocator(location, region_name=region_name) self.location = DataLocator(location, region_name=region_name)
if not self.location.exists(): if not self.location.exists():
raise DatasetAccessError("Dataset does not exist.") raise DatasetAccessError("Dataset does not exist.", HTTPStatus.NOT_FOUND)
# matrix_data_type is an enum value of type MatrixDataType # matrix_data_type is an enum value of type MatrixDataType
self.matrix_data_type = matrix_data_type self.matrix_data_type = matrix_data_type