Code

much nicer error messages when there's a templating error
authorrichard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2>
Fri, 6 Sep 2002 07:21:31 +0000 (07:21 +0000)
committerrichard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2>
Fri, 6 Sep 2002 07:21:31 +0000 (07:21 +0000)
git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/trunk@1084 57a73879-2fb5-44c3-a270-3262357dd7e2

TODO.txt
roundup/cgi/PageTemplates/Expressions.py
roundup/cgi/PageTemplates/PythonExpr.py
roundup/cgi/cgitb.py
roundup/cgi/client.py
roundup/cgi/templating.py

index df123510cc54b04d1fc9af593ead3b0c93cb3ce6..6d3f647c96a13faba5e8515d469e46a3ec92d23c 100644 (file)
--- a/TODO.txt
+++ b/TODO.txt
@@ -47,37 +47,36 @@ pending web: search "refinement"
                query values
 pending web: have roundup.cgi pick up instance config from the environment 
 pending web: UNIX init.d script for roundup-server
-pending web: modify cgitb to handle PageTemplate errors better (see how 
-             Zope handles __traceback_supplement__ and __traceback_info__)
 pending web: rewritten documentation (can come after the beta though so stuff
              is settled) ... including relevant file names in customisation doc
 
 bug: request.url is incorrect in cgi-bin environments
 
 
-done web: Re-enable link backrefs from messages (feature request #568714) (RJ)
-done web: have the page layout (header/footer) be templatable (RJ)
-done web: fixing the templating so it works (RJ)
+done web: Re-enable link backrefs from messages (feature request #568714)
+done web: have the page layout (header/footer) be templatable
+done web: fixing the templating so it works
 done web: re-work cgi interface to abstract out the explicit "issue"
-          interface (RJ)
+          interface
 done web: have index page handle mid-page errors better so header and
-          footer are still visible (RJ)
+          footer are still visible
 done hyperdb: write a backend for gadfly (it's as done as it's going to get)
-done hyperdb: full-text search also search certain String properties (RJ)
+done hyperdb: full-text search also search certain String properties
 done hyperdb: further split the *dbm backends from the core code, allowing
-              easier non-dict-like backends (eg metakit, RDB) (RJ)
-done hyperdb: fix the journal bloat (RJ)
+              easier non-dict-like backends (eg metakit, RDB)
+done hyperdb: fix the journal bloat
 done hyperdb: add Boolean and Number types (GM)
-done hyperdb: update design document (RJ)
-done hyperdb: entire database export and import (incl files) (RJ)
-done mailgw: better help message (feature request #558562) (RJ)
-done security: add info from doc/security.txt to design doc (RJ)
-done security: switch to sessions for web authentication (RJ)
+done hyperdb: update design document
+done hyperdb: entire database export and import (incl files)
+done mailgw: better help message (feature request #558562)
+done security: add info from doc/security.txt to design doc
+done security: switch to sessions for web authentication
 done security: implement and use the new logical control mechanisms
 done web: saving of named queries (GM, RJ)
-done web: handle "not found", access and item page render errors better (RJ)
-done web: fix double-submit by having new-item-submit redirect at end (RJ)
-done web: daemonify roundup-server (fork, logfile, pidfile) (RJ)
+done web: handle "not found", access and item page render errors better
+done web: fix double-submit by having new-item-submit redirect at end
+done web: daemonify roundup-server (fork, logfile, pidfile)
+done web: modify cgitb to display PageTemplate errors better
 
 rejected instance: the use of non-Python configuration files (ConfigParser)
 
index 105da31c1fbcfe5663484e790e62a1bb80a2f453..636da675833edbd96b3afad7c4e48d50d1b1b661 100644 (file)
@@ -17,7 +17,7 @@ Page Template-specific implementation of TALES, with handlers
 for Python expressions, string literals, and paths.
 """
 
-__version__='$Revision: 1.1 $'[11:-2]
+__version__='$Revision: 1.2 $'[11:-2]
 
 import re, sys
 from TALES import Engine, CompilerError, _valid_name, NAME_RE, \
@@ -112,7 +112,8 @@ class SubPathExpr:
                     # If the value isn't a string, assume it's a sequence
                     # of path names.
                     path[i:i+1] = list(val)
-        __traceback_info__ = base = self._base
+        base = self._base
+        __traceback_info__ = 'sub path expression "%s"'%base
         if base == 'CONTEXTS':
             ob = econtext.contexts
         else:
@@ -271,8 +272,8 @@ def restrictedTraverse(self, path, securityManager,
     object = self
     #print 'TRAVERSE', (object, path)
     while path:
-        __traceback_info__ = REQUEST
         name = path.pop()
+        __traceback_info__ = 'looking for "%s"'%name
 
         if isinstance(name, TupleType):
             object = apply(object, name)
index afa40d297c02e0633dc9eaeb258457de7e844f51..c0997703f45dd01387d7348564d214d3f26f8102 100644 (file)
@@ -14,7 +14,7 @@
 """Generic Python Expression Handler
 """
 
-__version__='$Revision: 1.1 $'[11:-2]
+__version__='$Revision: 1.2 $'[11:-2]
 
 from TALES import CompilerError
 from string import strip, split, join, replace, lstrip
@@ -60,7 +60,7 @@ class PythonExpr:
         return names
 
     def __call__(self, econtext):
-        __traceback_info__ = self.expr
+        __traceback_info__ = 'python expression "%s"'%self.expr
         f = self._f
         f.func_globals.update(self._bind_used_names(econtext))        
         return f()
index 21f19426d4eb55c39db339223fc1956904501f95..69a332aff12f7ac6e04fe42eaafebaeb5d710449 100644 (file)
@@ -1,7 +1,7 @@
 #
 # This module was written by Ka-Ping Yee, <ping@lfw.org>.
 # 
-# $Id: cgitb.py,v 1.1 2002-08-30 08:28:44 richard Exp $
+# $Id: cgitb.py,v 1.2 2002-09-06 07:21:31 richard Exp $
 
 __doc__ = """
 Extended CGI traceback handler by Ka-Ping Yee, <ping@lfw.org>.
@@ -16,6 +16,43 @@ def breaker():
             '<font color="white" size="-5"> > </font> ' +
             '</table>' * 5)
 
+def niceDict(indent, dict):
+    l = []
+    for k,v in dict.items():
+        l.append('%s%s: %r'%(indent,k,v))
+    return '\n'.join(l)
+
+def pt_html(context=5):
+    import cgi
+    etype, evalue = sys.exc_type, sys.exc_value
+    if type(etype) is types.ClassType:
+        etype = etype.__name__
+    pyver = 'Python ' + string.split(sys.version)[0] + '<br>' + sys.executable
+    head = pydoc.html.heading(
+        '<font size=+1><strong>%s</strong>: %s</font>'%(etype, evalue),
+        '#ffffff', '#777777', pyver)
+
+    head = head + _('<p>A problem occurred in your template</p><pre>')
+
+    l = []
+    for frame, file, lnum, func, lines, index in inspect.trace(context):
+        args, varargs, varkw, locals = inspect.getargvalues(frame)
+        if locals.has_key('__traceback_info__'):
+            ti = locals['__traceback_info__']
+            l.append(str(ti))
+        if locals.has_key('__traceback_supplement__'):
+            ts = locals['__traceback_supplement__']
+            if len(ts) == 2:
+                supp, context = ts
+                l.append('in template %r'%context.id)
+            elif len(ts) == 3:
+                supp, context, info = ts
+                l.append('in expression %r\n%s\n%s\n'%(info,
+                    niceDict('    ', context.global_vars),
+                    niceDict('    ', context.local_vars)))
+                # context._scope_stack))
+    return head + cgi.escape('\n'.join(l)) + '</pre><p>&nbsp;</p>'
+
 def html(context=5):
     etype, evalue = sys.exc_type, sys.exc_value
     if type(etype) is types.ClassType:
@@ -34,7 +71,8 @@ def html(context=5):
     traceback = []
     for frame, file, lnum, func, lines, index in inspect.trace(context):
         if file is None:
-            link = '&lt;file is None - probably inside <tt>eval</tt> or <tt>exec</tt>&gt;'
+            link = '''&lt;file is None - probably inside <tt>eval</tt> or
+                    <tt>exec</tt>&gt;'''
         else:
             file = os.path.abspath(file)
             link = '<a href="file:%s">%s</a>' % (file, pydoc.html.escape(file))
@@ -54,7 +92,7 @@ def html(context=5):
             traceback.append('<p>' + level)
             continue
 
-        # do a fil inspection
+        # do a file inspection
         names = []
         def tokeneater(type, token, start, end, line, names=names):
             if type == tokenize.NAME and token not in keyword.kwlist:
@@ -68,7 +106,8 @@ def html(context=5):
 
         try:
             tokenize.tokenize(linereader, tokeneater)
-        except IndexError: pass
+        except IndexError:
+            pass
         lvals = []
         for name in names:
             if name in frame.f_code.co_varnames:
@@ -83,11 +122,11 @@ def html(context=5):
                 else:
                     value = _('<em>undefined</em>')
                 name = '<em>global</em> <strong>%s</strong>' % name
-            lvals.append('%s&nbsp;= %s' % (name, value))
+            lvals.append('%s&nbsp;= %s'%(name, value))
         if lvals:
             lvals = string.join(lvals, ', ')
-            lvals = indent + '''
-<small><font color="#909090">%s</font></small><br>''' % lvals
+            lvals = indent + '<small><font color="#909090">%s'\
+                '</font></small><br>'%lvals
         else:
             lvals = ''
 
@@ -124,6 +163,9 @@ def handler():
 
 #
 # $Log: not supported by cvs2svn $
+# Revision 1.1  2002/08/30 08:28:44  richard
+# New CGI interface support
+#
 # Revision 1.10  2002/01/16 04:49:45  richard
 # Handle a special case that the CGI interface tickles. I need to check if
 # this needs fixing in python's core.
index 5a2ff2cd634eac578b5edd27a3a3f592d1ded281..122c0bc07a936cbfe03d271bd0155e5a94ea4b3d 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: client.py,v 1.18 2002-09-06 05:53:02 richard Exp $
+# $Id: client.py,v 1.19 2002-09-06 07:21:31 richard Exp $
 
 __doc__ = """
 WWW request handler (also used in the stand-alone server).
@@ -326,7 +326,7 @@ class Client:
                 '<li>'.join(pt._v_errors))
         except:
             # everything else
-            return cgitb.html()
+            return cgitb.pt_html()
 
     def content(self):
         ''' Callback used by the page template to render the content of 
@@ -903,10 +903,9 @@ class Client:
             return 0
         return 1
 
-    def XXXremove_action(self,  dre=re.compile(r'([^\d]+)(\d+)')):
+    def remove_action(self,  dre=re.compile(r'([^\d]+)(\d+)')):
         # XXX I believe this could be handled by a regular edit action that
         # just sets the multilink...
-        # XXX handle this !
         target = self.index_arg(':target')[0]
         m = dre.match(target)
         if m:
index 15f10c721756c8b9eb4218c7bc1a966bf71fc4c7..d29f31d6600aac87eae1d8eae92f55a511c90a2b 100644 (file)
@@ -98,7 +98,7 @@ def getTemplate(dir, name, extension, classname=None, request=None):
     # compile the template
     templates[key] = pt = RoundupPageTemplate()
     pt.write(open(src).read())
-    pt.id = name
+    pt.id = filename
     pt.mtime = time.time()
     return pt