From 1132f1e449ed83e09a00e808f7443adcf5b47028 Mon Sep 17 00:00:00 2001
From: Matt Jia <mjia@redhat.com>
Date: Aug 02 2017 00:25:54 +0000
Subject: return errors in JSON


---

diff --git a/functional-tests/test_api_v1.py b/functional-tests/test_api_v1.py
index 9e6e582..2f7c409 100644
--- a/functional-tests/test_api_v1.py
+++ b/functional-tests/test_api_v1.py
@@ -93,7 +93,7 @@ def test_cannot_make_decision_without_product_version(requests_session, greenwav
                               headers={'Content-Type': 'application/json'},
                               data=json.dumps(data))
     assert r.status_code == 400
-    assert u'Missing required product version' in r.text
+    assert u'Missing required product version' == r.json()['message']
 
 
 def test_cannot_make_decision_without_decision_context(requests_session, greenwave_server):
@@ -105,7 +105,7 @@ def test_cannot_make_decision_without_decision_context(requests_session, greenwa
                               headers={'Content-Type': 'application/json'},
                               data=json.dumps(data))
     assert r.status_code == 400
-    assert u'Missing required decision context' in r.text
+    assert u'Missing required decision context' == r.json()['message']
 
 
 def test_cannot_make_decision_without_subject(requests_session, greenwave_server):
@@ -117,7 +117,7 @@ def test_cannot_make_decision_without_subject(requests_session, greenwave_server
                               headers={'Content-Type': 'application/json'},
                               data=json.dumps(data))
     assert r.status_code == 400
-    assert u'Missing required subject' in r.text
+    assert u'Missing required subject' == r.json()['message']
 
 
 def test_404_for_inapplicable_policies(requests_session, greenwave_server):
@@ -130,7 +130,7 @@ def test_404_for_inapplicable_policies(requests_session, greenwave_server):
                               headers={'Content-Type': 'application/json'},
                               data=json.dumps(data))
     assert r.status_code == 404
-    assert u'Cannot find any applicable policies for rhel-7' in r.text
+    assert u'Cannot find any applicable policies for rhel-7' == r.json()['message']
 
 
 def test_make_a_decison_on_passed_result(requests_session, greenwave_server, testdatabuilder):
diff --git a/greenwave/app_factory.py b/greenwave/app_factory.py
index 1e7986c..e470b61 100644
--- a/greenwave/app_factory.py
+++ b/greenwave/app_factory.py
@@ -7,7 +7,10 @@ import yaml
 from flask import Flask
 from greenwave.logger import init_logging
 from greenwave.api_v1 import api
+from greenwave.utils import json_error
+
 from requests import ConnectionError, Timeout
+from werkzeug.exceptions import default_exceptions
 
 
 def load_config(app):
@@ -41,8 +44,10 @@ def create_app(config_obj=None):
     for policy_pathname in policy_pathnames:
         app.config['policies'].extend(yaml.safe_load_all(open(policy_pathname, 'r')))
     # register error handlers
-    app.register_error_handler(ConnectionError, lambda e: (str(e), 503))
-    app.register_error_handler(Timeout, lambda e: (str(e), 503))
+    for code in default_exceptions.iterkeys():
+        app.register_error_handler(code, json_error)
+    app.register_error_handler(ConnectionError, json_error)
+    app.register_error_handler(Timeout, json_error)
     # initialize logging
     init_logging(app)
     # register blueprints
diff --git a/greenwave/utils.py b/greenwave/utils.py
new file mode 100644
index 0000000..4853abf
--- /dev/null
+++ b/greenwave/utils.py
@@ -0,0 +1,24 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+from flask import jsonify, current_app
+from werkzeug.exceptions import HTTPException
+
+
+def json_error(error):
+    """
+    Return error responses in JSON.
+
+    :param error: One of Exceptions. It could be HTTPException, ConnectionError, or
+    Timeout.
+    :return: JSON error response.
+
+    """
+    if isinstance(error, HTTPException):
+        response = jsonify(message=error.description)
+        response.status_code = error.code
+    else:
+        # Could be ConnectionError or Timeout
+        current_app.logger.exception('Returning 500 to user.')
+        response = jsonify(message=str(error.message))
+        response.status_code = 500
+    return response

