diff --git a/gui/slick/views/404.mako b/gui/slick/views/404.mako new file mode 100644 index 0000000000000000000000000000000000000000..e090d5be0512ec7b9d9c9f7ff06a84bd94a3c345 --- /dev/null +++ b/gui/slick/views/404.mako @@ -0,0 +1,7 @@ +<%inherit file="/layouts/main.mako"/> +<%block name="content"> +<h1 class="header">${header}</h1> +<div class="align-center"> +You have reached this page by accident, please check the url. +</div> +</%block> diff --git a/gui/slick/views/500.mako b/gui/slick/views/500.mako new file mode 100644 index 0000000000000000000000000000000000000000..4a8547d4ac1b098715758f4b9873ef205ef2b1d0 --- /dev/null +++ b/gui/slick/views/500.mako @@ -0,0 +1,25 @@ +<%inherit file="/layouts/main.mako"/> + +<%block name="content"> +<h1 class="header">${header}</h1> +<p> +A mako error has occured.<br> +If this happened during an update a simple page refresh may be the solution.<br> +Mako errors that happen during updates may be a one time error if there were significant ui changes.<br> +</p> +<hr> +<a href="#mako-error" class="btn btn-default" data-toggle="collapse">Show/Hide Error</a> +<div id="mako-error" class="collapse"> +<br> +<div class="align-center"> +<pre> +<% filename, lineno, function, line = backtrace.traceback[-1] %> +File ${filename}:${lineno}, in ${function}: +% if line: +${line} +% endif +${str(backtrace.error.__class__.__name__)}: ${backtrace.error} +</pre> +</div> +</div> +</%block> diff --git a/sickbeard/webserve.py b/sickbeard/webserve.py index c0e35fb17a54c5526d53888221983a6e78103df8..986e7b2a84c8cc6ba635831b0d4b878b3c628ebb 100644 --- a/sickbeard/webserve.py +++ b/sickbeard/webserve.py @@ -81,6 +81,7 @@ except ImportError: from mako.template import Template as MakoTemplate from mako.lookup import TemplateLookup +from mako.exceptions import RichTraceback from tornado.routes import route from tornado.web import RequestHandler, HTTPError, authenticated @@ -106,7 +107,11 @@ def get_lookup(): mako_cache = ek(os.path.join, sickbeard.CACHE_DIR, 'mako') if mako_lookup is None: use_strict = sickbeard.BRANCH and sickbeard.BRANCH != 'master' - mako_lookup = TemplateLookup(directories=[mako_path], module_directory=mako_cache, format_exceptions=True, strict_undefined=use_strict) + mako_lookup = TemplateLookup(directories=[mako_path], + module_directory=mako_cache, + # format_exceptions=True, + strict_undefined=use_strict, + filesystem_checks=True) return mako_lookup @@ -158,9 +163,13 @@ class PageTemplate(MakoTemplate): kwargs[key] = self.arguments[key] kwargs['makoStartTime'] = time.time() - - return self.template.render_unicode(*args, **kwargs) - + try: + return self.template.render_unicode(*args, **kwargs) + except Exception: + kwargs['title'] = '500' + kwargs['header'] = 'Mako Error' + kwargs['backtrace'] = RichTraceback() + return get_lookup().get_template('500.mako').render_unicode(*args, **kwargs) class BaseHandler(RequestHandler): startTime = 0. @@ -181,7 +190,8 @@ class BaseHandler(RequestHandler): url = url[len(sickbeard.WEB_ROOT) + 1:] if url[:3] != 'api': - return self.redirect('/') + t = PageTemplate(rh=self, filename="404.mako") + return self.finish(t.render(title='404', header='Oops')) else: self.finish('Wrong API key used') diff --git a/sickbeard/webserveInit.py b/sickbeard/webserveInit.py index 7bbe79f5fdec394dd9c0cb76c4b690fb2e03265b..433fac267e5014f7783431f708116a9ec970cfb6 100644 --- a/sickbeard/webserveInit.py +++ b/sickbeard/webserveInit.py @@ -15,15 +15,15 @@ from tornado.ioloop import IOLoop from tornado.routes import route -class SRWebServer(threading.Thread): - def __init__(self, options={}, io_loop=None): +class SRWebServer(threading.Thread): # pylint: disable=too-many-instance-attributes + def __init__(self, options=None, io_loop=None): threading.Thread.__init__(self) self.daemon = True self.alive = True self.name = "TORNADO" self.io_loop = io_loop or IOLoop.current() - self.options = options + self.options = options or {} self.options.setdefault('port', 8081) self.options.setdefault('host', '0.0.0.0') self.options.setdefault('log_dir', None) @@ -33,6 +33,8 @@ class SRWebServer(threading.Thread): assert isinstance(self.options['port'], int) assert 'data_root' in self.options + self.server = None + # video root if sickbeard.ROOT_DIRS: root_dirs = sickbeard.ROOT_DIRS.split('|') @@ -94,14 +96,12 @@ class SRWebServer(threading.Thread): (r'%s/login(/?)' % self.options['web_root'], LoginHandler), (r'%s/logout(/?)' % self.options['web_root'], LogoutHandler), + # Web calendar handler (Needed because option Unprotected calendar) + (r'%s/calendar' % self.options['web_root'], CalendarHandler), + # webui handlers ] + route.get_routes(self.options['web_root'])) - # Web calendar handler (Needed because option Unprotected calendar) - self.app.add_handlers('.*$', [ - (r'%s/calendar' % self.options['web_root'], CalendarHandler), - ]) - # Static File Handlers self.app.add_handlers(".*$", [ # favicon @@ -146,12 +146,12 @@ class SRWebServer(threading.Thread): try: self.server.listen(self.options['port'], self.options['host']) - except: + except Exception: if sickbeard.LAUNCH_BROWSER and not self.daemon: sickbeard.launchBrowser('https' if sickbeard.ENABLE_HTTPS else 'http', self.options['port'], sickbeard.WEB_ROOT) logger.log(u"Launching browser and exiting") logger.log(u"Could not start webserver on port %s, already in use!" % self.options['port']) - os._exit(1) + os._exit(1) # pylint: disable=protected-access try: self.io_loop.start()