changeset 17:8186de188daf draft

Improve the run-time error handling in code-behinds.
author David Barts <n5jrn@me.com>
date Mon, 20 May 2019 07:34:46 -0700
parents 448fc3d534f8
children e88ab99914cf
files tincan.py
diffstat 1 files changed, 23 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/tincan.py	Thu May 16 19:58:02 2019 -0700
+++ b/tincan.py	Mon May 20 07:34:46 2019 -0700
@@ -15,6 +15,8 @@
 import py_compile
 from stat import S_ISDIR, S_ISREG
 from string import whitespace
+import traceback
+import urllib
 
 import bottle
 
@@ -330,9 +332,15 @@
 
     def __call__(self, e):
         bottle.request.environ[_FTYPE] = True
-        obj = self._class(bottle.request, e)
-        obj.handle()
-        return self._template.render(obj.export()).lstrip('\n')
+        try:
+            obj = self._class(bottle.request, e)
+            obj.handle()
+            return self._template.render(obj.export()).lstrip('\n')
+        except bottle.HTTPResponse as e:
+            return e
+        except Exception as e:
+            traceback.print_exc()
+            raise bottle.HTTPError(status=500, exception=e)
 
 class _TinCanRoute(object):
     """
@@ -516,14 +524,21 @@
         This gets called by the framework AFTER the page is launched.
         """
         target = None
-        obj = self._class(bottle.request, bottle.response)
         try:
+            obj = self._class(bottle.request, bottle.response)
             obj.handle()
             return self._body.render(obj.export()).lstrip('\n')
         except ForwardException as fwd:
             target = fwd.target
+        except bottle.HTTPResponse as e:
+            return e
+        except Exception as e:
+            traceback.print_exc()
+            raise bottle.HTTPError(status=500, exception=e)
         if target is None:
-            raise TinCanError("{0}: unexpected null target".format(self._urlpath))
+            message = "{0}: unexpected null target".format(self._urlpath)
+            sys.stderr.write(message + '\n')
+            raise bottle.HTTPError(status=500, exception=TinCanError(message))
         # We get here if we are doing a server-side programmatic
         # forward.
         environ = bottle.request.environ
@@ -532,7 +547,9 @@
         if _FLOOP not in environ:
             environ[_FLOOP] = set([self._urlpath])
         elif target in environ[_FLOOP]:
-            raise TinCanError("{0}: forward loop detected".format(environ[_FORIG]))
+            message = "{0}: forward loop detected".format(environ[_FORIG])
+            sys.stderr.write(message + '\n')
+            raise bottle.HTTPError(status=500, exception=TinCanError(message))
         environ[_FLOOP].add(target)
         environ['bottle.raw_path'] = target
         environ['PATH_INFO'] = urllib.parse.quote(target)