[LNT] r307447 - Make LNT client print server's error messages

Chris Matthews via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 7 15:30:46 PDT 2017


Author: cmatthews
Date: Fri Jul  7 15:30:46 2017
New Revision: 307447

URL: http://llvm.org/viewvc/llvm-project?rev=307447&view=rev
Log:
Make LNT client print server's error messages

The LNT client just prints error codes. In the case of server 500 errors
this is annoying when there are more than one kind of issues going on,
or if you are trying to debug why your data is not being accepted by the
server.  This adds a proper 404 and 500 error page to LNT, which returns
HTML or JSON. Update the submitted to request a JSON reply and if one is
returned, print that error message.

Modified:
    lnt/trunk/lnt/server/ui/app.py
    lnt/trunk/lnt/server/ui/templates/error.html
    lnt/trunk/lnt/server/ui/views.py
    lnt/trunk/lnt/util/ServerUtil.py
    lnt/trunk/tests/server/ui/V4Pages.py

Modified: lnt/trunk/lnt/server/ui/app.py
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/server/ui/app.py?rev=307447&r1=307446&r2=307447&view=diff
==============================================================================
--- lnt/trunk/lnt/server/ui/app.py (original)
+++ lnt/trunk/lnt/server/ui/app.py Fri Jul  7 15:30:46 2017
@@ -13,6 +13,9 @@ import jinja2
 from flask import current_app
 from flask import g
 from flask import session
+from flask import request
+from flask import jsonify
+from flask import render_template
 from flask_restful import Api
 from sqlalchemy.exc import DatabaseError
 from sqlalchemy.ext.declarative import DeclarativeMeta
@@ -66,9 +69,6 @@ class LNTObjectJSONEncoder(json.JSONEnco
         return json.JSONEncoder.default(self, obj)
 
 
-
-
-
 class Request(flask.Request):
     def __init__(self, *args, **kwargs):
         super(Request, self).__init__(*args, **kwargs)
@@ -166,6 +166,25 @@ class App(LNTExceptionLoggerFlask):
             """Make our session cookies last."""
             session.permanent = True
 
+        @app.errorhandler(404)
+        def page_not_found(e):
+            message = "{}: {}".format(e.name, e.description)
+            if request.accept_mimetypes.accept_json and \
+                    not request.accept_mimetypes.accept_html:
+                response = jsonify({'error': 'The page you are looking for does not exist.'})
+                response.status_code = 404
+                return response
+            return render_template('error.html', message=message), 404
+
+        @app.errorhandler(500)
+        def internal_server_error(e):
+            if request.accept_mimetypes.accept_json and \
+                    not request.accept_mimetypes.accept_html:
+                response = jsonify({'error': 'internal server error', 'message': repr(e)})
+                response.status_code = 500
+                return response
+            return render_template('error.html', message=e), 500
+
         return app
 
     @staticmethod

Modified: lnt/trunk/lnt/server/ui/templates/error.html
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/server/ui/templates/error.html?rev=307447&r1=307446&r2=307447&view=diff
==============================================================================
--- lnt/trunk/lnt/server/ui/templates/error.html (original)
+++ lnt/trunk/lnt/server/ui/templates/error.html Fri Jul  7 15:30:46 2017
@@ -1,10 +1,18 @@
-{% extends "layout.html" %}
-{% set components = [] %}
-{% block title %}Error{% endblock %}
-{% block body %}
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8"/>
 
+    <link href="{{ url_for('.static', filename='bootstrap/css/bootstrap.min.css')
+                }}" rel="stylesheet" media="screen"/>
+    <link href="{{ url_for('.static', filename='bootstrap/css/bootstrap-responsive.min.css')
+                }}" rel="stylesheet"/>
+</head>
+<body>
+
+<h1>LNT Error</h1>
 <div class="alert alert-error">
-Error: {{ message }}
+{{ message }}
 </div>
 
-{% endblock %}
+</body>
\ No newline at end of file

Modified: lnt/trunk/lnt/server/ui/views.py
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/server/ui/views.py?rev=307447&r1=307446&r2=307447&view=diff
==============================================================================
--- lnt/trunk/lnt/server/ui/views.py (original)
+++ lnt/trunk/lnt/server/ui/views.py Fri Jul  7 15:30:46 2017
@@ -1688,3 +1688,15 @@ def v4_matrix():
                            machine_name_common=machine_name_common,
                            machine_id_common=machine_id_common,
                            order_to_date=order_to_date)
+
+
+ at frontend.route("/explode")
+def explode():
+    """This route is going to exception. Used for testing 500 page."""
+    return 1/0
+
+
+ at frontend.route("/gone")
+def gone():
+    """This route returns 404. Used for testing 404 page."""
+    abort(404, "test")
\ No newline at end of file

Modified: lnt/trunk/lnt/util/ServerUtil.py
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/util/ServerUtil.py?rev=307447&r1=307446&r2=307447&view=diff
==============================================================================
--- lnt/trunk/lnt/util/ServerUtil.py (original)
+++ lnt/trunk/lnt/util/ServerUtil.py Fri Jul  7 15:30:46 2017
@@ -17,13 +17,26 @@ from lnt.util import ImportData
 # system to report to LNT, for example. It might be nice to factor the
 # simplified submit code into a separate utility.
 
+def _show_json_error(reply):
+    try:
+        error = json.loads(reply)
+    except ValueError:
+        print "error: {}".format(reply)
+        return
+    print "lnt server error: {}".format(error.get('error'))
+    print "error: {}".format(error.get('message'))
+
 def submitFileToServer(url, file, commit):
     with open(file, 'rb') as f:
         values = { 'input_data' : f.read(),
                    'commit' : ("0","1")[not not commit] }
-
+    headers = {'Accept': 'application/json'}
     data = urllib.urlencode(values)
-    response = urllib2.urlopen(urllib2.Request(url, data))
+    try:
+        response = urllib2.urlopen(urllib2.Request(url, data, headers=headers))
+    except urllib2.HTTPError as e:
+        _show_json_error(e.read())
+        return
     result_data = response.read()
 
     # The result is expected to be a JSON object.
@@ -37,9 +50,12 @@ def submitFileToServer(url, file, commit
         traceback.print_exc()
         print
         print "Result:"
-        print result_data
+        print "error:", result_data
         return
 
+    return reply
+
+
 def submitFileToInstance(path, file, commit):
     # Otherwise, assume it is a local url and submit to the default database
     # in the instance.
@@ -64,9 +80,11 @@ def submitFile(url, file, commit, verbos
         result = submitFileToInstance(url, file, commit)
     return result
 
+
 def submitFiles(url, files, commit, verbose):
     results = []
     for file in files:
         result = submitFile(url, file, commit, verbose)
-        results.append(result)
+        if result:
+            results.append(result)
     return results

Modified: lnt/trunk/tests/server/ui/V4Pages.py
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/tests/server/ui/V4Pages.py?rev=307447&r1=307446&r2=307447&view=diff
==============================================================================
--- lnt/trunk/tests/server/ui/V4Pages.py (original)
+++ lnt/trunk/tests/server/ui/V4Pages.py Fri Jul  7 15:30:46 2017
@@ -487,6 +487,12 @@ def main():
     check_json(client, '/db_default/v4/nts/graph?switch_min_mean=yes&plot.0=1.3.2&json=true&submit=Update')
     check_code(client, '/db_default/v4/nts/graph?switch_min_mean=yes&plot.0=1.3.2')
     check_json(client, '/db_default/v4/nts/graph?switch_min_mean=yes&plot.0=1.3.2&json=true')
+    app.testing = False
+    error_page = check_code(client, '/explode', expected_code=500)
+    assert "integer division or modulo by zero" in error_page.data
+
+    error_page = check_code(client, '/gone', expected_code=404)
+    assert "test" in error_page.data
 
 if __name__ == '__main__':
     main()




More information about the llvm-commits mailing list