From b62da236604352d6c8d693569652ab2c2d068d02 Mon Sep 17 00:00:00 2001 From: MinRK Date: Sun, 22 Dec 2013 10:15:38 -0800 Subject: [PATCH] render custom HTML for error pages --- IPython/html/base/handlers.py | 54 +++++++++++++++++++++++++++++------ IPython/html/notebookapp.py | 3 ++ 2 files changed, 49 insertions(+), 8 deletions(-) diff --git a/IPython/html/base/handlers.py b/IPython/html/base/handlers.py index f63438a7f..c9333804f 100644 --- a/IPython/html/base/handlers.py +++ b/IPython/html/base/handlers.py @@ -24,7 +24,13 @@ import os import stat import sys import traceback +try: + # py3 + from http.client import responses +except ImportError: + from httplib import responses +from jinja2 import TemplateNotFound from tornado import web try: @@ -44,14 +50,7 @@ UF_HIDDEN = getattr(stat, 'UF_HIDDEN', 32768) # Top-level handlers #----------------------------------------------------------------------------- -class RequestHandler(web.RequestHandler): - """RequestHandler with default variable setting.""" - - def render(*args, **kwargs): - kwargs.setdefault('message', '') - return web.RequestHandler.render(*args, **kwargs) - -class AuthenticatedHandler(RequestHandler): +class AuthenticatedHandler(web.RequestHandler): """A RequestHandler with an authenticated user.""" def clear_login_cookie(self): @@ -209,6 +208,45 @@ class IPythonHandler(AuthenticatedHandler): raise web.HTTPError(400, u'Invalid JSON in body of request') return model + def get_error_html(self, status_code, **kwargs): + """render custom error pages""" + exception = kwargs.get('exception') + message = '' + status_message = responses.get(status_code, 'Unknown') + if exception: + # get the custom message, if defined + try: + message = exception.log_message % exception.args + except Exception: + pass + + # construct the custom reason, if defined + reason = getattr(exception, 'reason', '') + if reason: + status_message = reason + + # build template namespace + ns = dict( + status_code=status_code, + status_message=status_message, + message=message, + exception=exception, + ) + + # render the template + try: + html = self.render_template('%s.html' % status_code, **ns) + except TemplateNotFound: + self.log.debug("No template for %d", status_code) + html = self.render_template('error.html', **ns) + return html + + +class Template404(IPythonHandler): + """Render our 404 template""" + def prepare(self): + raise web.HTTPError(404) + class AuthenticatedFileHandler(IPythonHandler, web.StaticFileHandler): """static files should only be accessible when logged in""" diff --git a/IPython/html/notebookapp.py b/IPython/html/notebookapp.py index 0dc0dc258..85b3fc26f 100644 --- a/IPython/html/notebookapp.py +++ b/IPython/html/notebookapp.py @@ -61,6 +61,7 @@ from tornado import web # Our own libraries from IPython.html import DEFAULT_STATIC_FILES_PATH +from .base.handlers import Template404 from .services.kernels.kernelmanager import MappingKernelManager from .services.notebooks.nbmanager import NotebookManager @@ -208,6 +209,8 @@ class NotebookWebApplication(web.Application): pattern = url_path_join(settings['base_project_url'], handler[0]) new_handler = tuple([pattern] + list(handler[1:])) new_handlers.append(new_handler) + # add 404 on the end, which will catch everything that falls through + new_handlers.append((r'(.*)', Template404)) return new_handlers