changeset 229:a951cd4ef361

serve: Print nested exception messages in the dev server.
author Ludovic Chabant <ludovic@chabant.com>
date Wed, 11 Feb 2015 08:27:52 -0800
parents 8015fb40c28b
children 016d42c23ba9
files build/messages/templates/error.html piecrust/resources/messages/critical.html piecrust/resources/messages/error.html piecrust/resources/messages/error404.html piecrust/serving.py
diffstat 5 files changed, 53 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/build/messages/templates/error.html	Wed Feb 11 08:21:40 2015 -0800
+++ b/build/messages/templates/error.html	Wed Feb 11 08:27:52 2015 -0800
@@ -3,10 +3,18 @@
 {% block content %}
 {{content|safe}}
 
+{# The following is `raw` because we want it to be in the
+   produced page, so it can then be templated on the fly 
+   with the error messages #}
 {% raw %}
 {% if details %}
 <div class="error-details">
-    {{ details|safe }}
+    <p>Error details:</p>
+    <ul>
+    {% for desc in details %}
+        <li>{{ desc }}</li>
+    {% endfor %}
+    </ul>
 </div>
 {% endif %}
 {% endraw %}
--- a/piecrust/resources/messages/critical.html	Wed Feb 11 08:21:40 2015 -0800
+++ b/piecrust/resources/messages/critical.html	Wed Feb 11 08:27:52 2015 -0800
@@ -64,7 +64,12 @@
 
 {% if details %}
 <div class="error-details">
-    {{ details|safe }}
+    <p>Error details:</p>
+    <ul>
+    {% for desc in details %}
+        <li>{{ desc }}</li>
+    {% endfor %}
+    </ul>
 </div>
 {% endif %}
 		</div>
--- a/piecrust/resources/messages/error.html	Wed Feb 11 08:21:40 2015 -0800
+++ b/piecrust/resources/messages/error.html	Wed Feb 11 08:27:52 2015 -0800
@@ -64,7 +64,12 @@
 
 {% if details %}
 <div class="error-details">
-    {{ details|safe }}
+    <p>Error details:</p>
+    <ul>
+    {% for desc in details %}
+        <li>{{ desc }}</li>
+    {% endfor %}
+    </ul>
 </div>
 {% endif %}
 		</div>
--- a/piecrust/resources/messages/error404.html	Wed Feb 11 08:21:40 2015 -0800
+++ b/piecrust/resources/messages/error404.html	Wed Feb 11 08:27:52 2015 -0800
@@ -64,7 +64,12 @@
 
 {% if details %}
 <div class="error-details">
-    {{ details|safe }}
+    <p>Error details:</p>
+    <ul>
+    {% for desc in details %}
+        <li>{{ desc }}</li>
+    {% endfor %}
+    </ul>
 </div>
 {% endif %}
 		</div>
--- a/piecrust/serving.py	Wed Feb 11 08:21:40 2015 -0800
+++ b/piecrust/serving.py	Wed Feb 11 08:27:52 2015 -0800
@@ -149,7 +149,7 @@
             response = self._try_serve_page(app, environ, request)
             return response(environ, start_response)
         except (RouteNotFoundError, SourceNotFoundError) as ex:
-            raise NotFound(str(ex))
+            raise NotFound(str(ex)) from ex
         except HTTPException:
             raise
         except Exception as ex:
@@ -158,7 +158,7 @@
                 raise
             msg = str(ex)
             logger.error(msg)
-            raise InternalServerError(msg)
+            raise InternalServerError(msg) from ex
 
     def _try_special_request(self, environ, request):
         static_mount = '/__piecrust_static/'
@@ -245,8 +245,8 @@
                     fac_metadata = {taxonomy.term_name: term_value}
                     break
         else:
-            raise SourceNotFoundError("Can't find path for: %s "
-                    "(looked in: %s)" %
+            raise SourceNotFoundError(
+                    "Can't find path for: %s (looked in: %s)" %
                     (req_path, [r.source_name for r, _ in routes]))
 
         # Build the page.
@@ -358,20 +358,36 @@
 
     def _handle_error(self, exception, environ, start_response):
         code = 500
-        path = 'error'
-        description = str(exception)
         if isinstance(exception, HTTPException):
             code = exception.code
-            description = exception.description
-            if isinstance(exception, NotFound):
-                path += '404'
+
+        path = 'error'
+        if isinstance(exception, NotFound):
+            path += '404'
+
+        descriptions = self._get_exception_descriptions(exception)
+
         env = Environment(loader=ErrorMessageLoader())
         template = env.get_template(path)
-        context = {'details': description}
+        context = {'details': descriptions}
         response = Response(template.render(context), mimetype='text/html')
         response.status_code = code
         return response(environ, start_response)
 
+    def _get_exception_descriptions(self, exception):
+        desc = []
+        while exception is not None:
+            if isinstance(exception, HTTPException):
+                desc.append(exception.description)
+            else:
+                desc.append(str(exception))
+
+            inner_ex = exception.__cause__
+            if inner_ex is None:
+                inner_ex = exception.__context__
+            exception = inner_ex
+        return desc
+
 
 class RouteNotFoundError(Exception):
     pass