From 5b7d0604b42eda1de87837f1eae6fb741e4e51eb Mon Sep 17 00:00:00 2001 From: Bernhard Mallinger Date: Wed, 3 Jan 2024 14:39:01 +0100 Subject: [PATCH] Simplify provider error handling (#1392) * Use generic error handling in get_collection_item * Use generic error handling in get_collection_items * Allow specifying a user-facing message in ProviderGenericError * ose generic error handling in more instances * Use generic error handling in more instances * Linting fixes --- pygeoapi/api.py | 399 ++++++++------------------------ pygeoapi/provider/base.py | 43 +++- pygeoapi/provider/csw_facade.py | 2 +- pygeoapi/provider/tile.py | 14 +- tests/test_api.py | 4 +- 5 files changed, 139 insertions(+), 323 deletions(-) diff --git a/pygeoapi/api.py b/pygeoapi/api.py index 2d1bb53..979d720 100644 --- a/pygeoapi/api.py +++ b/pygeoapi/api.py @@ -73,13 +73,8 @@ from pygeoapi.process.manager.base import get_manager from pygeoapi.plugin import load_plugin, PLUGINS from pygeoapi.provider.base import ( ProviderGenericError, ProviderConnectionError, ProviderNotFoundError, - ProviderInvalidDataError, ProviderInvalidQueryError, ProviderNoDataError, - ProviderQueryError, ProviderItemNotFoundError, ProviderTypeError, - ProviderRequestEntityTooLargeError) + ProviderTypeError) -from pygeoapi.provider.tile import (ProviderTileNotFoundError, - ProviderTileQueryError, - ProviderTilesetIdNotFoundError) from pygeoapi.models.cql import CQLModel from pygeoapi.util import (dategetter, RequestedProcessExecutionMode, DATETIME_FORMAT, UrlPrefetcher, @@ -1302,16 +1297,11 @@ class API: LOGGER.debug('Loading record provider') p = load_plugin('provider', get_provider_by_type( self.config['resources'][dataset]['providers'], 'record')) - except ProviderConnectionError: - msg = 'connection error (check logs)' + except ProviderGenericError as err: + LOGGER.error(err) return self.get_exception( - HTTPStatus.INTERNAL_SERVER_ERROR, headers, request.format, - 'NoApplicableCode', msg) - except ProviderQueryError: - msg = 'query error (check logs)' - return self.get_exception( - HTTPStatus.INTERNAL_SERVER_ERROR, headers, request.format, - 'NoApplicableCode', msg) + err.http_status_code, headers, request.format, + err.ogc_exception_code, err.message) queryables = { 'type': 'object', @@ -1483,16 +1473,11 @@ class API: return self.get_exception( HTTPStatus.BAD_REQUEST, headers, request.format, 'NoApplicableCode', msg) - except ProviderConnectionError: - msg = 'connection error (check logs)' + except ProviderGenericError as err: + LOGGER.error(err) return self.get_exception( - HTTPStatus.INTERNAL_SERVER_ERROR, headers, request.format, - 'NoApplicableCode', msg) - except ProviderQueryError: - msg = 'query error (check logs)' - return self.get_exception( - HTTPStatus.INTERNAL_SERVER_ERROR, headers, request.format, - 'NoApplicableCode', msg) + err.http_status_code, headers, request.format, + err.ogc_exception_code, err.message) crs_transform_spec = None if provider_type == 'feature': @@ -1654,30 +1639,11 @@ class API: select_properties=select_properties, crs_transform_spec=crs_transform_spec, q=q, language=prv_locale, filterq=filter_) - except ProviderInvalidQueryError as err: - LOGGER.error(err) - msg = f'query error: {err}' - return self.get_exception( - HTTPStatus.BAD_REQUEST, headers, request.format, - 'InvalidQuery', msg) - except ProviderConnectionError as err: - LOGGER.error(err) - msg = 'connection error (check logs)' - return self.get_exception( - HTTPStatus.INTERNAL_SERVER_ERROR, headers, request.format, - 'NoApplicableCode', msg) - except ProviderQueryError as err: - LOGGER.error(err) - msg = 'query error (check logs)' - return self.get_exception( - HTTPStatus.INTERNAL_SERVER_ERROR, headers, request.format, - 'NoApplicableCode', msg) except ProviderGenericError as err: LOGGER.error(err) - msg = 'generic error (check logs)' return self.get_exception( - HTTPStatus.INTERNAL_SERVER_ERROR, headers, request.format, - 'NoApplicableCode', msg) + err.http_status_code, headers, request.format, + err.ogc_exception_code, err.message) serialized_query_params = '' for k, v in request.params.items(): @@ -1931,16 +1897,11 @@ class API: return self.get_exception( HTTPStatus.BAD_REQUEST, headers, request.format, 'NoApplicableCode', msg) - except ProviderConnectionError: - msg = 'connection error (check logs)' + except ProviderGenericError as err: + LOGGER.error(err) return self.get_exception( - HTTPStatus.INTERNAL_SERVER_ERROR, headers, request.format, - 'NoApplicableCode', msg) - except ProviderQueryError: - msg = 'query error (check logs)' - return self.get_exception( - HTTPStatus.INTERNAL_SERVER_ERROR, headers, request.format, - 'NoApplicableCode', msg) + err.http_status_code, headers, request.format, + err.ogc_exception_code, err.message) LOGGER.debug('processing property parameters') for k, v in request.params.items(): @@ -2081,30 +2042,11 @@ class API: skip_geometry=skip_geometry, q=q, filterq=filter_) - except ProviderInvalidQueryError as err: - LOGGER.error(err) - msg = f'query error: {err}' - return self.get_exception( - HTTPStatus.BAD_REQUEST, headers, request.format, - 'InvalidQuery', msg) - except ProviderConnectionError as err: - LOGGER.error(err) - msg = 'connection error (check logs)' - return self.get_exception( - HTTPStatus.INTERNAL_SERVER_ERROR, headers, request.format, - 'NoApplicableCode', msg) - except ProviderQueryError as err: - LOGGER.error(err) - msg = 'query error (check logs)' - return self.get_exception( - HTTPStatus.INTERNAL_SERVER_ERROR, headers, request.format, - 'NoApplicableCode', msg) except ProviderGenericError as err: LOGGER.error(err) - msg = 'generic error (check logs)' return self.get_exception( - HTTPStatus.INTERNAL_SERVER_ERROR, headers, request.format, - 'NoApplicableCode', msg) + err.http_status_code, headers, request.format, + err.ogc_exception_code, err.message) return headers, HTTPStatus.OK, to_json(content, self.pretty_print) @@ -2184,11 +2126,16 @@ class API: LOGGER.debug('Creating item') try: identifier = p.create(request.data) - except (ProviderInvalidDataError, TypeError) as err: + except TypeError as err: msg = str(err) return self.get_exception( HTTPStatus.BAD_REQUEST, headers, request.format, 'InvalidParameterValue', msg) + except ProviderGenericError as err: + LOGGER.error(err) + return self.get_exception( + err.http_status_code, headers, request.format, + err.ogc_exception_code, err.message) headers['Location'] = f'{self.get_collections_url()}/{dataset}/items/{identifier}' # noqa @@ -2198,11 +2145,16 @@ class API: LOGGER.debug('Updating item') try: _ = p.update(identifier, request.data) - except (ProviderInvalidDataError, TypeError) as err: + except TypeError as err: msg = str(err) return self.get_exception( HTTPStatus.BAD_REQUEST, headers, request.format, 'InvalidParameterValue', msg) + except ProviderGenericError as err: + LOGGER.error(err) + return self.get_exception( + err.http_status_code, headers, request.format, + err.ogc_exception_code, err.message) return headers, HTTPStatus.NO_CONTENT, '' @@ -2211,10 +2163,10 @@ class API: try: _ = p.delete(identifier) except ProviderGenericError as err: - msg = str(err) + LOGGER.error(err) return self.get_exception( - HTTPStatus.BAD_REQUEST, headers, request.format, - 'InvalidParameterValue', msg) + err.http_status_code, headers, request.format, + err.ogc_exception_code, err.message) return headers, HTTPStatus.OK, '' @@ -2268,16 +2220,11 @@ class API: return self.get_exception( HTTPStatus.BAD_REQUEST, headers, request.format, 'InvalidParameterValue', msg) - except ProviderConnectionError: - msg = 'connection error (check logs)' + except ProviderGenericError as err: + LOGGER.error(err) return self.get_exception( - HTTPStatus.INTERNAL_SERVER_ERROR, headers, request.format, - 'NoApplicableCode', msg) - except ProviderQueryError: - msg = 'query error (check logs)' - return self.get_exception( - HTTPStatus.INTERNAL_SERVER_ERROR, headers, request.format, - 'NoApplicableCode', msg) + err.http_status_code, headers, request.format, + err.ogc_exception_code, err.message) crs_transform_spec = None if provider_type == 'feature': @@ -2306,28 +2253,11 @@ class API: language=prv_locale, crs_transform_spec=crs_transform_spec, ) - except ProviderConnectionError as err: - LOGGER.error(err) - msg = 'connection error (check logs)' - return self.get_exception( - HTTPStatus.INTERNAL_SERVER_ERROR, headers, request.format, - 'NoApplicableCode', msg) - except ProviderItemNotFoundError: - msg = 'identifier not found' - return self.get_exception(HTTPStatus.NOT_FOUND, headers, - request.format, 'NotFound', msg) - except ProviderQueryError as err: - LOGGER.error(err) - msg = 'query error (check logs)' - return self.get_exception( - HTTPStatus.INTERNAL_SERVER_ERROR, headers, request.format, - 'NoApplicableCode', msg) except ProviderGenericError as err: LOGGER.error(err) - msg = 'generic error (check logs)' return self.get_exception( - HTTPStatus.INTERNAL_SERVER_ERROR, headers, request.format, - 'NoApplicableCode', msg) + err.http_status_code, headers, request.format, + err.ogc_exception_code, err.message) if content is None: msg = 'identifier not found' @@ -2448,16 +2378,11 @@ class API: return self.get_exception( HTTPStatus.NOT_FOUND, headers, format_, 'InvalidParameterValue', msg) - except ProviderTypeError: - msg = 'invalid provider type' + except ProviderGenericError as err: + LOGGER.error(err) return self.get_exception( - HTTPStatus.BAD_REQUEST, headers, format_, - 'NoApplicableCode', msg) - except ProviderConnectionError: - msg = 'connection error (check logs)' - return self.get_exception( - HTTPStatus.INTERNAL_SERVER_ERROR, headers, format_, - 'NoApplicableCode', msg) + err.http_status_code, headers, request.format, + err.ogc_exception_code, err.message) LOGGER.debug('Processing bbox parameter') @@ -2536,21 +2461,11 @@ class API: LOGGER.debug('Querying coverage') try: data = p.query(**query_args) - except ProviderInvalidQueryError as err: - msg = f'query error: {err}' + except ProviderGenericError as err: + LOGGER.error(err) return self.get_exception( - HTTPStatus.BAD_REQUEST, headers, format_, - 'InvalidParameterValue', msg) - except ProviderNoDataError: - msg = 'No data found' - return self.get_exception( - HTTPStatus.NO_CONTENT, headers, format_, - 'InvalidParameterValue', msg) - except ProviderQueryError: - msg = 'query error (check logs)' - return self.get_exception( - HTTPStatus.INTERNAL_SERVER_ERROR, headers, format_, - 'NoApplicableCode', msg) + err.http_status_code, headers, request.format, + err.ogc_exception_code, err.message) mt = collection_def['format']['name'] if format_ == mt: # native format @@ -2597,16 +2512,11 @@ class API: return self.get_exception( HTTPStatus.NOT_FOUND, headers, format_, 'InvalidParameterValue', msg) - except ProviderTypeError: - msg = 'invalid provider type' + except ProviderGenericError as err: + LOGGER.error(err) return self.get_exception( - HTTPStatus.INTERNAL_SERVER_ERROR, headers, format_, - 'NoApplicableCode', msg) - except ProviderConnectionError: - msg = 'connection error (check logs)' - return self.get_exception( - HTTPStatus.INTERNAL_SERVER_ERROR, headers, format_, - 'NoApplicableCode', msg) + err.http_status_code, headers, request.format, + err.ogc_exception_code, err.message) if format_ == F_JSON: return headers, HTTPStatus.OK, to_json(data, self.pretty_print) @@ -2654,16 +2564,11 @@ class API: return self.get_exception( HTTPStatus.NOT_FOUND, headers, format_, 'InvalidParameterValue', msg) - except ProviderTypeError: - msg = 'invalid provider type' + except ProviderGenericError as err: + LOGGER.error(err) return self.get_exception( - HTTPStatus.INTERNAL_SERVER_ERROR, headers, format_, - 'NoApplicableCode', msg) - except ProviderConnectionError: - msg = 'connection error (check logs)' - return self.get_exception( - HTTPStatus.INTERNAL_SERVER_ERROR, headers, format_, - 'NoApplicableCode', msg) + err.http_status_code, headers, request.format, + err.ogc_exception_code, err.message) if format_ == F_JSON: return headers, HTTPStatus.OK, to_json(data, self.pretty_print) @@ -2717,16 +2622,11 @@ class API: return self.get_exception( HTTPStatus.BAD_REQUEST, headers, request.format, 'InvalidParameterValue', msg) - except ProviderConnectionError: - msg = 'connection error (check logs)' + except ProviderGenericError as err: + LOGGER.error(err) return self.get_exception( - HTTPStatus.INTERNAL_SERVER_ERROR, headers, request.format, - 'NoApplicableCode', msg) - except ProviderQueryError: - msg = 'query error (check logs)' - return self.get_exception( - HTTPStatus.INTERNAL_SERVER_ERROR, headers, request.format, - 'NoApplicableCode', msg) + err.http_status_code, headers, request.format, + err.ogc_exception_code, err.message) tiles = { 'links': [], @@ -2867,33 +2767,11 @@ class API: return self.get_exception( HTTPStatus.BAD_REQUEST, headers, format_, 'InvalidParameterValue', msg) - except ProviderConnectionError as err: - LOGGER.error(err) - msg = 'connection error (check logs)' - return self.get_exception( - HTTPStatus.INTERNAL_SERVER_ERROR, headers, format_, - 'NoApplicableCode', msg) - except ProviderTilesetIdNotFoundError: - msg = 'Tileset id not found' - return self.get_exception( - HTTPStatus.NOT_FOUND, headers, format_, 'NotFound', msg) - except ProviderTileQueryError as err: - LOGGER.error(err) - msg = 'Tile not found' - return self.get_exception( - HTTPStatus.INTERNAL_SERVER_ERROR, headers, format_, - 'NoApplicableCode', msg) - except ProviderTileNotFoundError as err: - LOGGER.error(err) - msg = 'Tile not found (check logs)' - return self.get_exception( - HTTPStatus.NOT_FOUND, headers, format_, 'NoMatch', msg) except ProviderGenericError as err: LOGGER.error(err) - msg = 'Generic error (check logs)' return self.get_exception( - HTTPStatus.INTERNAL_SERVER_ERROR, headers, format_, - 'NoApplicableCode', msg) + err.http_status_code, headers, request.format, + err.ogc_exception_code, err.message) @gzip @pre_process @@ -2933,16 +2811,11 @@ class API: return self.get_exception( HTTPStatus.BAD_REQUEST, headers, request.format, 'InvalidParameterValue', msg) - except ProviderConnectionError: - msg = 'connection error (check logs)' + except ProviderGenericError as err: + LOGGER.error(err) return self.get_exception( - HTTPStatus.INTERNAL_SERVER_ERROR, headers, request.format, - 'InvalidParameterValue', msg) - except ProviderQueryError: - msg = 'query error (check logs)' - return self.get_exception( - HTTPStatus.INTERNAL_SERVER_ERROR, headers, request.format, - 'InvalidParameterValue', msg) + err.http_status_code, headers, request.format, + err.ogc_exception_code, err.message) # Get provider language (if any) prv_locale = l10n.get_plugin_locale(t, request.raw_locale) @@ -3034,24 +2907,11 @@ class API: LOGGER.error(exception) return headers, HTTPStatus.NOT_FOUND, to_json( exception, self.pretty_print) - except ProviderTypeError: - exception = { - 'code': 'NoApplicableCode', - 'description': 'invalid provider type' - } - headers['Content-type'] = 'application/json' - LOGGER.error(exception) - return headers, HTTPStatus.BAD_REQUEST, to_json( - exception, self.pretty_print) - except ProviderConnectionError: - exception = { - 'code': 'NoApplicableCode', - 'description': 'connection error (check logs)' - } - headers['Content-type'] = 'application/json' - LOGGER.error(exception) - return headers, HTTPStatus.INTERNAL_SERVER_ERROR, to_json( - exception, self.pretty_print) + except ProviderGenericError as err: + LOGGER.error(err) + return self.get_exception( + err.http_status_code, headers, request.format, + err.ogc_exception_code, err.message) query_args['format_'] = request.params.get('f', 'png') query_args['style'] = style @@ -3111,33 +2971,11 @@ class API: LOGGER.debug('Generating map') try: data = p.query(**query_args) - except ProviderInvalidQueryError as err: - exception = { - 'code': 'NoApplicableCode', - 'description': f'query error: {err}' - } - LOGGER.error(exception) - headers['Content-type'] = 'application/json' - return headers, HTTPStatus.BAD_REQUEST, to_json( - exception, self.pretty_print) - except ProviderNoDataError: - exception = { - 'code': 'NoApplicableCode', - 'description': 'No data found' - } - LOGGER.debug(exception) - headers['Content-type'] = 'application/json' - return headers, HTTPStatus.NO_CONTENT, to_json( - exception, self.pretty_print) - except ProviderQueryError: - exception = { - 'code': 'NoApplicableCode', - 'description': 'query error (check logs)' - } - LOGGER.error(exception) - headers['Content-type'] = 'application/json' - return headers, HTTPStatus.INTERNAL_SERVER_ERROR, to_json( - exception, self.pretty_print) + except ProviderGenericError as err: + LOGGER.error(err) + return self.get_exception( + err.http_status_code, headers, request.format, + err.ogc_exception_code, err.message) mt = collection_def['format']['name'] @@ -3188,50 +3026,20 @@ class API: LOGGER.error(exception) return headers, HTTPStatus.NOT_FOUND, to_json( exception, self.pretty_print) - except ProviderTypeError: - exception = { - 'code': 'NoApplicableCode', - 'description': 'invalid provider type' - } - LOGGER.error(exception) - return headers, HTTPStatus.BAD_REQUEST, to_json( - exception, self.pretty_print) - except ProviderConnectionError: - exception = { - 'code': 'NoApplicableCode', - 'description': 'connection error (check logs)' - } - LOGGER.error(exception) - return headers, HTTPStatus.INTERNAL_SERVER_ERROR, to_json( - exception, self.pretty_print) + except ProviderGenericError as err: + LOGGER.error(err) + return self.get_exception( + err.http_status_code, headers, request.format, + err.ogc_exception_code, err.message) LOGGER.debug('Generating legend') try: data = p.get_legend(style, request.params.get('f', 'png')) - except ProviderInvalidQueryError as err: - exception = { - 'code': 'NoApplicableCode', - 'description': f'query error: {err}' - } - LOGGER.error(exception) - return headers, HTTPStatus.BAD_REQUEST, to_json( - exception, self.pretty_print) - except ProviderNoDataError: - exception = { - 'code': 'NoApplicableCode', - 'description': 'No data found' - } - LOGGER.debug(exception) - return headers, HTTPStatus.NO_CONTENT, to_json( - exception, self.pretty_print) - except ProviderQueryError: - exception = { - 'code': 'NoApplicableCode', - 'description': 'query error (check logs)' - } - LOGGER.error(exception) - return headers, HTTPStatus.INTERNAL_SERVER_ERROR, to_json( - exception, self.pretty_print) + except ProviderGenericError as err: + LOGGER.error(err) + return self.get_exception( + err.http_status_code, headers, request.format, + err.ogc_exception_code, err.message) mt = collection_def['format']['name'] @@ -3811,21 +3619,11 @@ class API: try: p = load_plugin('provider', get_provider_by_type( collections[dataset]['providers'], 'edr')) - except ProviderTypeError: - msg = 'invalid provider type' + except ProviderGenericError as err: + LOGGER.error(err) return self.get_exception( - HTTPStatus.INTERNAL_SERVER_ERROR, headers, - request.format, 'NoApplicableCode', msg) - except ProviderConnectionError: - msg = 'connection error (check logs)' - return self.get_exception( - HTTPStatus.INTERNAL_SERVER_ERROR, headers, - request.format, 'NoApplicableCode', msg) - except ProviderQueryError: - msg = 'query error (check logs)' - return self.get_exception( - HTTPStatus.INTERNAL_SERVER_ERROR, headers, - request.format, 'NoApplicableCode', msg) + err.http_status_code, headers, request.format, + err.ogc_exception_code, err.message) if instance is not None and not p.get_instance(instance): msg = 'Invalid instance identifier' @@ -3862,24 +3660,11 @@ class API: try: data = p.query(**query_args) - except ProviderInvalidQueryError as err: - msg = f'query error: {err}' + except ProviderGenericError as err: + LOGGER.error(err) return self.get_exception( - HTTPStatus.BAD_REQUEST, headers, request.format, - 'InvalidQuery', msg) - except ProviderNoDataError: - msg = 'No data found' - return self.get_exception( - HTTPStatus.NO_CONTENT, headers, request.format, 'NoMatch', msg) - except ProviderQueryError: - msg = 'query error (check logs)' - return self.get_exception( - HTTPStatus.INTERNAL_SERVER_ERROR, headers, request.format, - 'NoApplicableCode', msg) - except ProviderRequestEntityTooLargeError as err: - return self.get_exception( - HTTPStatus.REQUEST_ENTITY_TOO_LARGE, headers, request.format, - 'NoApplicableCode', str(err)) + err.http_status_code, headers, request.format, + err.ogc_exception_code, err.message) if request.format == F_HTML: # render content = render_j2_template(self.tpl_config, diff --git a/pygeoapi/provider/base.py b/pygeoapi/provider/base.py index 6bdc225..9eeeb55 100644 --- a/pygeoapi/provider/base.py +++ b/pygeoapi/provider/base.py @@ -30,6 +30,7 @@ import json import logging from enum import Enum +from http import HTTPStatus LOGGER = logging.getLogger(__name__) @@ -273,37 +274,57 @@ class BaseProvider: class ProviderGenericError(Exception): """provider generic error""" - pass + ogc_exception_code = 'NoApplicableCode' + http_status_code = HTTPStatus.INTERNAL_SERVER_ERROR + default_msg = 'generic error (check logs)' + + def __init__(self, msg=None, *args, user_msg=None) -> None: + # if only a user_msg is provided, use it as msg + if user_msg and not msg: + msg = user_msg + super().__init__(msg, *args) + self.user_msg = user_msg + + @property + def message(self): + return self.user_msg if self.user_msg else self.default_msg class ProviderConnectionError(ProviderGenericError): """provider connection error""" - pass + default_msg = 'connection error (check logs)' class ProviderTypeError(ProviderGenericError): """provider type error""" - pass + default_msg = 'invalid provider type' + http_status_code = HTTPStatus.BAD_REQUEST class ProviderInvalidQueryError(ProviderGenericError): """provider invalid query error""" - pass + ogc_exception_code = 'InvalidQuery' + http_status_code = HTTPStatus.BAD_REQUEST + default_msg = "query error" class ProviderQueryError(ProviderGenericError): """provider query error""" - pass + default_msg = 'query error (check logs)' class ProviderItemNotFoundError(ProviderGenericError): """provider item not found query error""" - pass + ogc_exception_code = 'NotFound' + http_status_code = HTTPStatus.NOT_FOUND + default_msg = 'identifier not found' class ProviderNoDataError(ProviderGenericError): """provider no data error""" - pass + ogc_exception_code = 'InvalidParameterValue' + http_status_code = HTTPStatus.NO_CONTENT + default_msg = 'No data found' class ProviderNotFoundError(ProviderGenericError): @@ -323,4 +344,10 @@ class ProviderInvalidDataError(ProviderGenericError): class ProviderRequestEntityTooLargeError(ProviderGenericError): """provider request entity too large error""" - pass + http_status_code = HTTPStatus.REQUEST_ENTITY_TOO_LARGE + + def __init__(self, msg=None, *args, user_msg=None) -> None: + if msg and not user_msg: + # This error type shows the error by default + user_msg = msg + super().__init__(msg, *args, user_msg=user_msg) diff --git a/pygeoapi/provider/csw_facade.py b/pygeoapi/provider/csw_facade.py index 372a59b..cfb5bb8 100644 --- a/pygeoapi/provider/csw_facade.py +++ b/pygeoapi/provider/csw_facade.py @@ -144,7 +144,7 @@ class CSWFacadeProvider(BaseProvider): if p[0] not in list(self.record_mappings.keys()): msg = f'Invalid property: {p[0]}' LOGGER.error(msg) - raise ProviderInvalidQueryError(msg) + raise ProviderInvalidQueryError(user_msg=msg) prop = self.record_mappings[p[0]][0] constraints.append(fes.PropertyIsEqualTo(prop, p[1])) diff --git a/pygeoapi/provider/tile.py b/pygeoapi/provider/tile.py index ed0714d..2a4e455 100644 --- a/pygeoapi/provider/tile.py +++ b/pygeoapi/provider/tile.py @@ -30,8 +30,10 @@ # ================================================================= import logging +from http import HTTPStatus -from pygeoapi.provider.base import ProviderGenericError +from pygeoapi.provider.base import ( + ProviderGenericError, ProviderItemNotFoundError) LOGGER = logging.getLogger(__name__) @@ -125,14 +127,16 @@ class BaseTileProvider: class ProviderTileQueryError(ProviderGenericError): """provider tile query error""" - pass + default_msg = 'Tile not found' -class ProviderTileNotFoundError(ProviderGenericError): +class ProviderTileNotFoundError(ProviderItemNotFoundError): """provider tile not found error""" - pass + default_msg = 'Tile not found (check logs)' class ProviderTilesetIdNotFoundError(ProviderTileQueryError): """provider tileset matrix query error""" - pass + default_msg = 'Tileset id not found' + http_status_code = HTTPStatus.NOT_FOUND + ogc_exception_code = 'NotFound' diff --git a/tests/test_api.py b/tests/test_api.py index 582bb6e..ad576b1 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -1380,7 +1380,7 @@ def test_get_coverage_domainset(config, api_): rsp_headers, code, response = api_.get_collection_coverage_domainset( req, 'obs') - assert code == HTTPStatus.INTERNAL_SERVER_ERROR + assert code == HTTPStatus.BAD_REQUEST rsp_headers, code, response = api_.get_collection_coverage_domainset( req, 'gdps-temperature') @@ -1399,7 +1399,7 @@ def test_get_collection_coverage_rangetype(config, api_): rsp_headers, code, response = api_.get_collection_coverage_rangetype( req, 'obs') - assert code == HTTPStatus.INTERNAL_SERVER_ERROR + assert code == HTTPStatus.BAD_REQUEST rsp_headers, code, response = api_.get_collection_coverage_rangetype( req, 'gdps-temperature')