From 88a207d2b35c421254ef3f0f807187e619554cd4 Mon Sep 17 00:00:00 2001 From: Luca Pireddu Date: Wed, 25 Nov 2020 17:53:45 +0100 Subject: [PATCH] Return API errors following JSON-API convention --- tdmq/api.py | 6 ++++-- tdmq/app.py | 13 ++++++++++++- tdmq/client/client.py | 10 ++++++++-- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/tdmq/api.py b/tdmq/api.py index 68a091e..b1eb981 100644 --- a/tdmq/api.py +++ b/tdmq/api.py @@ -109,8 +109,10 @@ def sources_post(): data = request.json try: tdmq_ids = db.load_sources(data) - except tdmq.errors.DuplicateItemException: - raise wex.Conflict() + except tdmq.errors.DuplicateItemException as e: + logger.debug("Duplicate item exception") + logger.debug(e) + raise wex.Conflict("Duplicate source id") return jsonify(tdmq_ids) diff --git a/tdmq/app.py b/tdmq/app.py index 4532e0a..9b565b3 100644 --- a/tdmq/app.py +++ b/tdmq/app.py @@ -140,7 +140,18 @@ def create_app(test_config=None): @app.errorhandler(wex.HTTPException) def handle_errors(e): - return jsonify({"error": ERROR_CODES.get(e.code)}), e.code + # adopt the JSON API convention for errors: https://jsonapi.org/examples/#error-objects + error = { + "status": str(e.code), + "source": { "pointer": flask.request.path }, + "title": ERROR_CODES.get(e.code), + } + if e.description: + error['detail'] = e.description + + response_data = { 'errors' : [ error ] } + + return jsonify(response_data), e.code @app.teardown_appcontext def teardown_db(arg): diff --git a/tdmq/client/client.py b/tdmq/client/client.py index 9ea03a1..b586aa5 100644 --- a/tdmq/client/client.py +++ b/tdmq/client/client.py @@ -4,6 +4,7 @@ import numpy as np import requests +from requests.exceptions import HTTPError import tiledb from tdmq.client.sources import NonScalarSource, ScalarSource @@ -44,7 +45,7 @@ def __init__(self, tdmq_base_url=None, auth_token=None): self.tiledb_ctx = None self.tiledb_vfs = None self.headers = {'Authorization': f'Bearer {auth_token}'} if auth_token is not None else {} - + def requires_connection(func): """ @@ -121,7 +122,12 @@ def register_source(self, definition, nslots=10*24*3600*365): _logger.error('Failure in creating tiledb array: %s, cleaning up', e) self._destroy_source(tdmq_id) raise TdmqError(f"Internal failure in registering {definition.get('id', '(id unavailable)')}.") - return self.get_source(tdmq_id) + try: + return self.get_source(tdmq_id) + except HTTPError as e: + _logger.error("Failed to retrieve newly created source %s", tdmq_id) + raise + @requires_connection def add_records(self, records):