From: richard Date: Fri, 6 Sep 2002 07:21:31 +0000 (+0000) Subject: much nicer error messages when there's a templating error X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=ef558f6cdc27a8289fffae910e873ccf3ef1bfcd;p=roundup.git much nicer error messages when there's a templating error git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/trunk@1084 57a73879-2fb5-44c3-a270-3262357dd7e2 --- diff --git a/TODO.txt b/TODO.txt index df12351..6d3f647 100644 --- 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) diff --git a/roundup/cgi/PageTemplates/Expressions.py b/roundup/cgi/PageTemplates/Expressions.py index 105da31..636da67 100644 --- a/roundup/cgi/PageTemplates/Expressions.py +++ b/roundup/cgi/PageTemplates/Expressions.py @@ -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) diff --git a/roundup/cgi/PageTemplates/PythonExpr.py b/roundup/cgi/PageTemplates/PythonExpr.py index afa40d2..c099770 100644 --- a/roundup/cgi/PageTemplates/PythonExpr.py +++ b/roundup/cgi/PageTemplates/PythonExpr.py @@ -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() diff --git a/roundup/cgi/cgitb.py b/roundup/cgi/cgitb.py index 21f1942..69a332a 100644 --- a/roundup/cgi/cgitb.py +++ b/roundup/cgi/cgitb.py @@ -1,7 +1,7 @@ # # This module was written by Ka-Ping Yee, . # -# $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, . @@ -16,6 +16,43 @@ def breaker(): ' > ' + '' * 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] + '
' + sys.executable + head = pydoc.html.heading( + '%s: %s'%(etype, evalue), + '#ffffff', '#777777', pyver) + + head = head + _('

A problem occurred in your template

')
+
+    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)) + '

 

' + 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 = '<file is None - probably inside eval or exec>' + link = '''<file is None - probably inside eval or + exec>''' else: file = os.path.abspath(file) link = '%s' % (file, pydoc.html.escape(file)) @@ -54,7 +92,7 @@ def html(context=5): traceback.append('

' + 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 = _('undefined') name = 'global %s' % name - lvals.append('%s = %s' % (name, value)) + lvals.append('%s = %s'%(name, value)) if lvals: lvals = string.join(lvals, ', ') - lvals = indent + ''' -%s
''' % lvals + lvals = indent + '%s'\ + '
'%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. diff --git a/roundup/cgi/client.py b/roundup/cgi/client.py index 5a2ff2c..122c0bc 100644 --- a/roundup/cgi/client.py +++ b/roundup/cgi/client.py @@ -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: '

  • '.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: diff --git a/roundup/cgi/templating.py b/roundup/cgi/templating.py index 15f10c7..d29f31d 100644 --- a/roundup/cgi/templating.py +++ b/roundup/cgi/templating.py @@ -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