[Checkins] SVN: Sandbox/malthe/chameleon.core/ Enabled error handler for macro renderer.

Malthe Borch mborch at gmail.com
Wed Nov 5 11:37:54 EST 2008


Log message for revision 92800:
  Enabled error handler for macro renderer.

Changed:
  U   Sandbox/malthe/chameleon.core/CHANGES.txt
  U   Sandbox/malthe/chameleon.core/src/chameleon/core/template.py
  U   Sandbox/malthe/chameleon.core/src/chameleon/core/template.txt
  U   Sandbox/malthe/chameleon.core/src/chameleon/core/utils.py

-=-
Modified: Sandbox/malthe/chameleon.core/CHANGES.txt
===================================================================
--- Sandbox/malthe/chameleon.core/CHANGES.txt	2008-11-05 15:35:28 UTC (rev 92799)
+++ Sandbox/malthe/chameleon.core/CHANGES.txt	2008-11-05 16:37:51 UTC (rev 92800)
@@ -4,6 +4,8 @@
 HEAD
 ~~~~
 
+- Enabled error handler for macro renderer. [malthe]
+
 - Added error handler which adds debugging information to the
   exception object's string output (in debug-mode only). [malthe]
 

Modified: Sandbox/malthe/chameleon.core/src/chameleon/core/template.py
===================================================================
--- Sandbox/malthe/chameleon.core/src/chameleon/core/template.py	2008-11-05 15:35:28 UTC (rev 92799)
+++ Sandbox/malthe/chameleon.core/src/chameleon/core/template.py	2008-11-05 16:37:51 UTC (rev 92800)
@@ -1,7 +1,6 @@
 import os
 import sys
 import utils
-import pprint
 import config
 import doctypes
 import filecache
@@ -20,6 +19,8 @@
         'text': translation.Compiler.from_text}
 
     format = 'xml'
+    filename = '<string>'
+    
     implicit_doctype = doctypes.xhtml
     explicit_doctype = None
     
@@ -36,6 +37,12 @@
         if doctype is not None:            
             self.explicit_doctype = doctype
         
+    def __repr__(self):
+        return u"<%s %s>" % (self.__class__.__name__, self.filename)
+
+    def __call__(self, **kwargs):
+        return self.render(**kwargs)
+    
     @property
     def macros(self):
         return Macros(self.render_macro)
@@ -63,55 +70,26 @@
 
     def render(self, **kwargs):
         template = self.cook_check(parameters=kwargs)
-        if config.DEBUG_MODE is False:
-            return template.render(**kwargs)
-        
-        try:
-            return template.render(**kwargs)
-        except:
-            tb = sys.exc_info()[-1]
-            lineno = tb.tb_next.tb_next.tb_lineno-1
-            del tb
+        return self.render_template(template, **kwargs)
 
-            # locate source code annotation (these are available from
-            # the template source as comments)
-            source = template.source.split('\n')
-            for i in reversed(range(lineno)):
-                if source[i].lstrip().startswith('#'):
-                    annotation = source[i].split('#', 1)[-1].lstrip()
-                    break
-            else:
-                annotation = ""
-                
-            formatted_arguments = pprint.pformat(kwargs).split('\n')
-            
-            # indent consecutive arguments for readability
-            for index, string in enumerate(formatted_arguments[1:]):
-                formatted_arguments[index+1] = " "*15 + string
-            
-            utils.reraise(
-                sys.exc_info(),
-                ("Caught exception rendering template."
-                 "\n\n"
-                 " - Expression: %s\n"
-                 " - Instance:   %s\n"
-                 " - Arguments:  %s\n"
-                 ) % (annotation, repr(self), "\n".join(formatted_arguments)))
-                      
     def render_macro(self, macro, global_scope=False, parameters={}):
         template = self.cook_check(
             parameters=parameters, macro=macro, global_scope=global_scope)
-        return template.render(**parameters)
+        return self.render_template(template, **parameters)
     
     def render_xinclude(self, **kwargs):
         return self.render_macro("", parameters=kwargs)
 
-    def __repr__(self):
-        return u"<%s %d>" % (self.__class__.__name__, id(self))
-
-    def __call__(self, **kwargs):
-        return self.render(**kwargs)
-    
+    def render_template(self, __template__, **kwargs):
+        if config.DEBUG_MODE is False:
+            return __template__.render(**kwargs)
+        
+        try:
+            return __template__.render(**kwargs)
+        except:
+            utils.raise_template_exception(
+                __template__.source, repr(self), kwargs, sys.exc_info())
+                      
 class TemplateFile(Template):
     """Constructs a template object using the template language
     defined by ``parser``. Must be passed an absolute (or
@@ -197,9 +175,6 @@
         except (IOError, OSError):
             return 0
 
-    def __repr__(self):
-        return u"<%s %s>" % (self.__class__.__name__, self.filename)
-
 class XIncludes(object):
     """Dynamic XInclude registry providing a ``get``-method that will
     resolve a filename to a template instance. Format must be

Modified: Sandbox/malthe/chameleon.core/src/chameleon/core/template.txt
===================================================================
--- Sandbox/malthe/chameleon.core/src/chameleon/core/template.txt	2008-11-05 15:35:28 UTC (rev 92799)
+++ Sandbox/malthe/chameleon.core/src/chameleon/core/template.txt	2008-11-05 16:37:51 UTC (rev 92800)
@@ -104,7 +104,7 @@
     ...
   RuntimeError: Caught exception rendering template.
     ...
-    dummy()
+    "dummy()"
     ...
   NameError: ...
 

Modified: Sandbox/malthe/chameleon.core/src/chameleon/core/utils.py
===================================================================
--- Sandbox/malthe/chameleon.core/src/chameleon/core/utils.py	2008-11-05 15:35:28 UTC (rev 92799)
+++ Sandbox/malthe/chameleon.core/src/chameleon/core/utils.py	2008-11-05 16:37:51 UTC (rev 92800)
@@ -2,6 +2,7 @@
 from zope import component
 
 import sys
+import pprint
 import config
 import logging
 import interfaces
@@ -254,12 +255,43 @@
 def py_attr(name):
     return "{%s}%s" % (config.PY_NS, name)
 
-def reraise(exc_info=(None, None, None), error_msg=""):
-    """Re-raise the latest exception given by ``exc_info`` tuple (see
-    ``sys.exc_info``) with an additional ``error_msg`` text."""
+def raise_template_exception(source, description, kwargs, exc_info):
+    """Re-raise exception raised while calling ``template``, given by
+    the ``exc_info`` tuple (see ``sys.exc_info``)."""
 
+    # omit keyword arguments that begin with an underscore; these are
+    # used internally be the template engine and should not be exposed
+    kwargs = kwargs.copy()
+    map(kwargs.__delitem__, [k for k in kwargs if k.startswith('_')])
+
+    # format keyword arguments; consecutive arguments are indented for
+    # readability
+    formatted_arguments = pprint.pformat(kwargs).split('\n')
+    for index, string in enumerate(formatted_arguments[1:]):
+        formatted_arguments[index+1] = " "*15 + string
+
+    # extract line number from traceback object
     cls, exc, tb = exc_info
+    lineno = tb.tb_next.tb_next.tb_lineno-1
 
+    # locate source code annotation (these are available from
+    # the template source as comments)
+    source = source.split('\n')
+    for i in reversed(range(lineno)):
+        if source[i].lstrip().startswith('#'):
+            annotation = source[i].split('#', 1)[-1].lstrip()
+            break
+    else:
+        annotation = ""
+
+    error_msg = (
+        "Caught exception rendering template."
+        "\n\n"
+        " - Expression: \"%s\"\n"
+        " - Instance:   %s\n"
+        " - Arguments:  %s\n"
+        ) % (annotation, description, "\n".join(formatted_arguments))    
+
     __dict__ = exc.__dict__
     error_string = str(exc)
     



More information about the Checkins mailing list