Mercurial > p > roundup > code
comparison roundup/cgi/cgitb.py @ 1065:0f9aa62917bd
much nicer error messages when there's a templating error
| author | Richard Jones <richard@users.sourceforge.net> |
|---|---|
| date | Fri, 06 Sep 2002 07:21:31 +0000 |
| parents | 55ab0c5b49f9 |
| children | cf22c87d6fce |
comparison
equal
deleted
inserted
replaced
| 1064:fca22f820f87 | 1065:0f9aa62917bd |
|---|---|
| 1 # | 1 # |
| 2 # This module was written by Ka-Ping Yee, <ping@lfw.org>. | 2 # This module was written by Ka-Ping Yee, <ping@lfw.org>. |
| 3 # | 3 # |
| 4 # $Id: cgitb.py,v 1.1 2002-08-30 08:28:44 richard Exp $ | 4 # $Id: cgitb.py,v 1.2 2002-09-06 07:21:31 richard Exp $ |
| 5 | 5 |
| 6 __doc__ = """ | 6 __doc__ = """ |
| 7 Extended CGI traceback handler by Ka-Ping Yee, <ping@lfw.org>. | 7 Extended CGI traceback handler by Ka-Ping Yee, <ping@lfw.org>. |
| 8 """ | 8 """ |
| 9 | 9 |
| 13 | 13 |
| 14 def breaker(): | 14 def breaker(): |
| 15 return ('<body bgcolor="white">' + | 15 return ('<body bgcolor="white">' + |
| 16 '<font color="white" size="-5"> > </font> ' + | 16 '<font color="white" size="-5"> > </font> ' + |
| 17 '</table>' * 5) | 17 '</table>' * 5) |
| 18 | |
| 19 def niceDict(indent, dict): | |
| 20 l = [] | |
| 21 for k,v in dict.items(): | |
| 22 l.append('%s%s: %r'%(indent,k,v)) | |
| 23 return '\n'.join(l) | |
| 24 | |
| 25 def pt_html(context=5): | |
| 26 import cgi | |
| 27 etype, evalue = sys.exc_type, sys.exc_value | |
| 28 if type(etype) is types.ClassType: | |
| 29 etype = etype.__name__ | |
| 30 pyver = 'Python ' + string.split(sys.version)[0] + '<br>' + sys.executable | |
| 31 head = pydoc.html.heading( | |
| 32 '<font size=+1><strong>%s</strong>: %s</font>'%(etype, evalue), | |
| 33 '#ffffff', '#777777', pyver) | |
| 34 | |
| 35 head = head + _('<p>A problem occurred in your template</p><pre>') | |
| 36 | |
| 37 l = [] | |
| 38 for frame, file, lnum, func, lines, index in inspect.trace(context): | |
| 39 args, varargs, varkw, locals = inspect.getargvalues(frame) | |
| 40 if locals.has_key('__traceback_info__'): | |
| 41 ti = locals['__traceback_info__'] | |
| 42 l.append(str(ti)) | |
| 43 if locals.has_key('__traceback_supplement__'): | |
| 44 ts = locals['__traceback_supplement__'] | |
| 45 if len(ts) == 2: | |
| 46 supp, context = ts | |
| 47 l.append('in template %r'%context.id) | |
| 48 elif len(ts) == 3: | |
| 49 supp, context, info = ts | |
| 50 l.append('in expression %r\n%s\n%s\n'%(info, | |
| 51 niceDict(' ', context.global_vars), | |
| 52 niceDict(' ', context.local_vars))) | |
| 53 # context._scope_stack)) | |
| 54 return head + cgi.escape('\n'.join(l)) + '</pre><p> </p>' | |
| 18 | 55 |
| 19 def html(context=5): | 56 def html(context=5): |
| 20 etype, evalue = sys.exc_type, sys.exc_value | 57 etype, evalue = sys.exc_type, sys.exc_value |
| 21 if type(etype) is types.ClassType: | 58 if type(etype) is types.ClassType: |
| 22 etype = etype.__name__ | 59 etype = etype.__name__ |
| 32 | 69 |
| 33 indent = '<tt><small>%s</small> </tt>' % (' ' * 5) | 70 indent = '<tt><small>%s</small> </tt>' % (' ' * 5) |
| 34 traceback = [] | 71 traceback = [] |
| 35 for frame, file, lnum, func, lines, index in inspect.trace(context): | 72 for frame, file, lnum, func, lines, index in inspect.trace(context): |
| 36 if file is None: | 73 if file is None: |
| 37 link = '<file is None - probably inside <tt>eval</tt> or <tt>exec</tt>>' | 74 link = '''<file is None - probably inside <tt>eval</tt> or |
| 75 <tt>exec</tt>>''' | |
| 38 else: | 76 else: |
| 39 file = os.path.abspath(file) | 77 file = os.path.abspath(file) |
| 40 link = '<a href="file:%s">%s</a>' % (file, pydoc.html.escape(file)) | 78 link = '<a href="file:%s">%s</a>' % (file, pydoc.html.escape(file)) |
| 41 args, varargs, varkw, locals = inspect.getargvalues(frame) | 79 args, varargs, varkw, locals = inspect.getargvalues(frame) |
| 42 if func == '?': | 80 if func == '?': |
| 52 | 90 |
| 53 if index is None or file is None: | 91 if index is None or file is None: |
| 54 traceback.append('<p>' + level) | 92 traceback.append('<p>' + level) |
| 55 continue | 93 continue |
| 56 | 94 |
| 57 # do a fil inspection | 95 # do a file inspection |
| 58 names = [] | 96 names = [] |
| 59 def tokeneater(type, token, start, end, line, names=names): | 97 def tokeneater(type, token, start, end, line, names=names): |
| 60 if type == tokenize.NAME and token not in keyword.kwlist: | 98 if type == tokenize.NAME and token not in keyword.kwlist: |
| 61 if token not in names: | 99 if token not in names: |
| 62 names.append(token) | 100 names.append(token) |
| 66 lnum[0] = lnum[0] + 1 | 104 lnum[0] = lnum[0] + 1 |
| 67 return line | 105 return line |
| 68 | 106 |
| 69 try: | 107 try: |
| 70 tokenize.tokenize(linereader, tokeneater) | 108 tokenize.tokenize(linereader, tokeneater) |
| 71 except IndexError: pass | 109 except IndexError: |
| 110 pass | |
| 72 lvals = [] | 111 lvals = [] |
| 73 for name in names: | 112 for name in names: |
| 74 if name in frame.f_code.co_varnames: | 113 if name in frame.f_code.co_varnames: |
| 75 if locals.has_key(name): | 114 if locals.has_key(name): |
| 76 value = pydoc.html.repr(locals[name]) | 115 value = pydoc.html.repr(locals[name]) |
| 81 if frame.f_globals.has_key(name): | 120 if frame.f_globals.has_key(name): |
| 82 value = pydoc.html.repr(frame.f_globals[name]) | 121 value = pydoc.html.repr(frame.f_globals[name]) |
| 83 else: | 122 else: |
| 84 value = _('<em>undefined</em>') | 123 value = _('<em>undefined</em>') |
| 85 name = '<em>global</em> <strong>%s</strong>' % name | 124 name = '<em>global</em> <strong>%s</strong>' % name |
| 86 lvals.append('%s = %s' % (name, value)) | 125 lvals.append('%s = %s'%(name, value)) |
| 87 if lvals: | 126 if lvals: |
| 88 lvals = string.join(lvals, ', ') | 127 lvals = string.join(lvals, ', ') |
| 89 lvals = indent + ''' | 128 lvals = indent + '<small><font color="#909090">%s'\ |
| 90 <small><font color="#909090">%s</font></small><br>''' % lvals | 129 '</font></small><br>'%lvals |
| 91 else: | 130 else: |
| 92 lvals = '' | 131 lvals = '' |
| 93 | 132 |
| 94 excerpt = [] | 133 excerpt = [] |
| 95 i = lnum - index | 134 i = lnum - index |
| 122 print breaker() | 161 print breaker() |
| 123 print html() | 162 print html() |
| 124 | 163 |
| 125 # | 164 # |
| 126 # $Log: not supported by cvs2svn $ | 165 # $Log: not supported by cvs2svn $ |
| 166 # Revision 1.1 2002/08/30 08:28:44 richard | |
| 167 # New CGI interface support | |
| 168 # | |
| 127 # Revision 1.10 2002/01/16 04:49:45 richard | 169 # Revision 1.10 2002/01/16 04:49:45 richard |
| 128 # Handle a special case that the CGI interface tickles. I need to check if | 170 # Handle a special case that the CGI interface tickles. I need to check if |
| 129 # this needs fixing in python's core. | 171 # this needs fixing in python's core. |
| 130 # | 172 # |
| 131 # Revision 1.9 2002/01/08 11:56:24 richard | 173 # Revision 1.9 2002/01/08 11:56:24 richard |
