gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] [taler-blog] branch master updated: proper backend error ha


From: gnunet
Subject: [GNUnet-SVN] [taler-blog] branch master updated: proper backend error handling
Date: Tue, 16 Jan 2018 03:21:55 +0100

This is an automated email from the git hooks/post-receive script.

dold pushed a commit to branch master
in repository blog.

The following commit(s) were added to refs/heads/master by this push:
     new f78a9b9  proper backend error handling
f78a9b9 is described below

commit f78a9b9d30db62724978d874ce480328b295b29d
Author: Florian Dold <address@hidden>
AuthorDate: Tue Jan 16 03:21:46 2018 +0100

    proper backend error handling
---
 talerblog/blog/blog.py              | 76 ++++++++++++++++++++++++++-----------
 talerblog/blog/templates/error.html | 24 ++++++++++++
 talerblog/helpers.py                | 22 -----------
 3 files changed, 78 insertions(+), 44 deletions(-)

diff --git a/talerblog/blog/blog.py b/talerblog/blog/blog.py
index c11fe3d..0272442 100644
--- a/talerblog/blog/blog.py
+++ b/talerblog/blog/blog.py
@@ -20,24 +20,21 @@
 Implement URL handlers and payment logic for the blog merchant.
 """
 
-from urllib.parse import urljoin, quote, parse_qsl
+from urllib.parse import urljoin, quote
 import logging
 import os
+import traceback
 import uuid
 import base64
 import requests
 import flask
 from talerblog.talerconfig import TalerConfig
-from ..helpers import (make_url, \
-    expect_parameter, join_urlparts, \
-    get_query_string, backend_error)
-from ..blog.content import (ARTICLES, \
-    get_article_file, get_image_file)
+from ..helpers import make_url, join_urlparts
+from ..blog.content import ARTICLES, get_article_file, get_image_file
 
 
 BASE_DIR = os.path.dirname(os.path.abspath(__file__))
 app = flask.Flask(__name__, template_folder=BASE_DIR)
-app.debug = True
 app.secret_key = base64.b64encode(os.urandom(64)).decode('utf-8')
 
 LOGGER = logging.getLogger(__name__)
@@ -52,6 +49,7 @@ app.config.from_object(__name__)
 
 @app.context_processor
 def utility_processor():
+    # These helpers will be available in templates
     def url(my_url):
         return join_urlparts(flask.request.script_root, my_url)
     def env(name, default=None):
@@ -59,6 +57,49 @@ def utility_processor():
     return dict(url=url, env=env)
 
 
+def err_abort(**params):
+    t = flask.render_template("templates/error.html", **params)
+    flask.abort(flask.make_response(t))
+
+
+def backend_get(endpoint, params):
+    try:
+        resp = requests.get(urljoin(BACKEND_URL, endpoint), params=params)
+    except requests.ConnectionError:
+        err_abort(message="Could not establish connection to backend")
+    try:
+        response_json = resp.json()
+    except ValueError:
+        err_abort(message="Could not parse response from backend")
+    if resp.status_code != 200:
+        err_abort(message="Backend returned error status",
+                  json=response_json, status_code=resp.status_code)
+    return response_json
+
+
+def backend_post(endpoint, json):
+    try:
+        resp = requests.post(urljoin(BACKEND_URL, endpoint), json=json)
+    except requests.ConnectionError:
+        err_abort(message="Could not establish connection to backend")
+    try:
+        response_json = resp.json()
+    except ValueError:
+        err_abort(message="Could not parse response from backend",
+                  status_code=resp.status_code)
+    if resp.status_code != 200:
+        err_abort(message="Backend returned error status",
+                  json=response_json, status_code=resp.status_code)
+    return response_json
+
+
address@hidden(Exception)
+def internal_error(e)
+    return flask.render_template("templates/error.html",
+                                 message="Internal error",
+                                 stack=traceback.format_exc())
+
+
 @app.route("/")
 def index():
     return flask.render_template("templates/index.html",
@@ -82,14 +123,12 @@ def refund():
     order_id = payed_articles.get(article_name)
     if not order_id:
         return flask.jsonify(dict(error="Aborting refund: article not 
payed")), 401
-    resp = requests.post(urljoin(BACKEND_URL, "refund"),
+    resp = backend_post(urljoin(BACKEND_URL, "refund"),
                          json=dict(order_id=order_id,
                                    refund=ARTICLE_AMOUNT,
                                    reason="Demo reimbursement",
                                    instance=INSTANCE))
-    if resp.status_code != 200:
-        return backend_error(resp)
-    if pay_status.get("refund_redirect_url"):
+    if resp.get("refund_redirect_url"):
         return flask.redirect(pay_status["refund_redirect_url"])
     flask.abort(500)
 
@@ -115,11 +154,7 @@ def article(article_name, data=None):
             amount=ARTICLE_AMOUNT,
             instance=INSTANCE,
         )
-        resp = requests.post(urljoin(BACKEND_URL, "proposal"),
-                             json=dict(order=order))
-        if resp.status_code != 200:
-            return backend_error(resp)
-        proposal_resp = resp.json()
+        proposal_resp = backend_post("proposal", dict(order=order))
         order_id = proposal_resp["order_id"]
 
     session_sig = flask.request.args.get("session_id")
@@ -136,17 +171,14 @@ def article(article_name, data=None):
         session_sig=session_sig,
     )
 
-    resp = requests.get(urljoin(BACKEND_URL, "check-payment"), 
params=pay_params)
-    if resp.status_code != 200:
-        return backend_error(resp)
-
-    pay_status = resp.json()
+    pay_status = backend_get("check-payment", pay_params)
 
     if pay_status.get("payment_redirect_url"):
         return flask.redirect(pay_status["payment_redirect_url"])
 
     if pay_status.get("refunded"):
-        return flask.render_template("templates/article_refunded.html", 
article_name=article_name)
+        return flask.render_template("templates/article_refunded.html",
+                                     article_name=article_name)
 
     if pay_status.get("paid"):
         article_info = ARTICLES.get(article_name)
diff --git a/talerblog/blog/templates/error.html 
b/talerblog/blog/templates/error.html
new file mode 100644
index 0000000..016321b
--- /dev/null
+++ b/talerblog/blog/templates/error.html
@@ -0,0 +1,24 @@
+{% extends "templates/base.html" %}
+{% block main %}
+  <h1>An Error Occored</h1>
+
+  <p>{{ message }}</p>
+
+  {% if status_code %}
+  <p>The backend returned status code {{ status_code }}.</p>
+  {% endif %}
+
+  {% if json %}
+  <p>Backend Response:</p>
+  <pre>
+    {{ json }}
+  </pre>
+  {% endif %}
+
+  {% if stack %}
+  <p>Stack trace:</p>
+  <pre>
+    {{ stack }}
+  </pre>
+  {% endif %}
+{% endblock main %}
diff --git a/talerblog/helpers.py b/talerblog/helpers.py
index 614e463..83eccd5 100644
--- a/talerblog/helpers.py
+++ b/talerblog/helpers.py
@@ -77,25 +77,3 @@ def make_url(page, *query_params):
     # urlencode is overly eager with quoting, the wallet right now
     # needs some characters unquoted.
     return url.replace("%24", "$").replace("%7B", "{").replace("%7D", "}")
-
-
-def expect_parameter(name, alt=None):
-    value = flask.request.args.get(name, None)
-    if value is None and alt is None:
-        LOGGER.error("Missing parameter '%s' from '%s'." % (name, 
flask.request.args))
-        raise MissingParameterException(name)
-    return value if value else alt
-
-
-def get_query_string():
-    return flask.request.query_string
-
-def backend_error(requests_response):
-    LOGGER.error("Backend error: status code: "
-                 + str(requests_response.status_code))
-    try:
-        return flask.jsonify(requests_response.json()), 
requests_response.status_code
-    except json.decoder.JSONDecodeError:
-        LOGGER.error("Backend error (NO JSON returned): status code: "
-                     + str(requests_response.status_code))
-        return flask.jsonify(dict(error="Backend died, no JSON got from it")), 
502

-- 
To stop receiving notification emails like this one, please contact
address@hidden



reply via email to

[Prev in Thread] Current Thread [Next in Thread]