Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 6b5a48d

Browse files
committed
Initial check-in of cgitb.
A few enhancements are pending, but this should work reliably.
1 parent e5e5059 commit 6b5a48d

1 file changed

Lines changed: 182 additions & 0 deletions

File tree

Lib/cgitb.py

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
"""Handle exceptions in CGI scripts by formatting tracebacks into nice HTML.
2+
3+
To enable this module, do:
4+
5+
import cgitb; cgitb.enable()
6+
7+
at the top of your CGI script. The optional arguments to enable() are:
8+
9+
display - if true, tracebacks are displayed in the web browser
10+
logdir - if set, tracebacks are written to files in this directory
11+
12+
By default, tracebacks are displayed but not written to files.
13+
14+
Alternatively, if you have caught an exception and want cgitb to display it
15+
for you, call cgitb.handle(). The optional argument to handle() is a 3-item
16+
tuple (etype, evalue, etb) just like the value of sys.exc_info()."""
17+
18+
__author__ = 'Ka-Ping Yee'
19+
__version__ = '$Revision$'
20+
21+
def reset():
22+
"""Return a string that resets the CGI and browser to a known state."""
23+
return '''<!--: spam
24+
Content-Type: text/html
25+
26+
<body bgcolor="#f0f0ff"><font color="#f0f0ff" size="-5"> -->
27+
<body bgcolor="#f0f0ff"><font color="#f0f0ff" size="-5"> --> -->
28+
</font> </font> </font> </script> </object> </blockquote> </pre>
29+
</table> </table> </table> </table> </table> </font> </font> </font>'''
30+
31+
def html(etype, evalue, etb, context=5):
32+
"""Return a nice HTML document describing the traceback."""
33+
import sys, os, types, time, traceback
34+
import keyword, tokenize, linecache, inspect, pydoc
35+
36+
if type(etype) is types.ClassType:
37+
etype = etype.__name__
38+
pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable
39+
date = time.ctime(time.time())
40+
head = '<body bgcolor="#f0f0ff">' + pydoc.html.heading(
41+
'<big><big><strong>%s</strong></big></big>' % str(etype),
42+
'#ffffff', '#aa55cc', pyver + '<br>' + date) + '''
43+
<p>A problem occurred in a Python script.
44+
Here is the sequence of function calls leading up to
45+
the error, with the most recent (innermost) call last.'''
46+
47+
indent = '<tt><small>' + '&nbsp;' * 5 + '</small>&nbsp;</tt>'
48+
frames = []
49+
records = inspect.getinnerframes(etb, context)
50+
for frame, file, lnum, func, lines, index in records:
51+
file = file and os.path.abspath(file) or '?'
52+
link = '<a href="file:%s">%s</a>' % (file, pydoc.html.escape(file))
53+
args, varargs, varkw, locals = inspect.getargvalues(frame)
54+
if func == '?':
55+
call = ''
56+
else:
57+
def eqrepr(value): return '=' + pydoc.html.repr(value)
58+
call = 'in <strong>%s</strong>' % func + inspect.formatargvalues(
59+
args, varargs, varkw, locals, formatvalue=eqrepr)
60+
61+
names = []
62+
def tokeneater(type, token, start, end, line):
63+
if type == tokenize.NAME and token not in keyword.kwlist:
64+
if token not in names: names.append(token)
65+
if type == tokenize.NEWLINE: raise IndexError
66+
def linereader(lnum=[lnum]):
67+
line = linecache.getline(file, lnum[0])
68+
lnum[0] += 1
69+
return line
70+
71+
try:
72+
tokenize.tokenize(linereader, tokeneater)
73+
except IndexError: pass
74+
lvals = []
75+
for name in names:
76+
if name in frame.f_code.co_varnames:
77+
if locals.has_key(name):
78+
value = pydoc.html.repr(locals[name])
79+
else:
80+
value = '<em>undefined</em>'
81+
name = '<strong>%s</strong>' % name
82+
else:
83+
if frame.f_globals.has_key(name):
84+
value = pydoc.html.repr(frame.f_globals[name])
85+
else:
86+
value = '<em>undefined</em>'
87+
name = '<em>global</em> <strong>%s</strong>' % name
88+
lvals.append('%s&nbsp;= %s' % (name, value))
89+
if lvals:
90+
lvals = indent + '''
91+
<small><font color="#909090">%s</font></small><br>''' % (', '.join(lvals))
92+
else:
93+
lvals = ''
94+
95+
level = '''
96+
<table width="100%%" bgcolor="#d8bbff" cellspacing=0 cellpadding=2 border=0>
97+
<tr><td>%s %s</td></tr></table>\n''' % (link, call)
98+
excerpt = []
99+
if index is not None:
100+
i = lnum - index
101+
for line in lines:
102+
num = '<small><font color="#909090">%s</font></small>' % (
103+
'&nbsp;' * (5-len(str(i))) + str(i))
104+
line = '<tt>%s&nbsp;%s</tt>' % (num, pydoc.html.preformat(line))
105+
if i == lnum:
106+
line = '''
107+
<table width="100%%" bgcolor="#ffccee" cellspacing=0 cellpadding=0 border=0>
108+
<tr><td>%s</td></tr></table>\n''' % line
109+
excerpt.append('\n' + line)
110+
if i == lnum:
111+
excerpt.append(lvals)
112+
i = i + 1
113+
frames.append('<p>' + level + '\n'.join(excerpt))
114+
115+
exception = ['<p><strong>%s</strong>: %s' % (str(etype), str(evalue))]
116+
if type(evalue) is types.InstanceType:
117+
for name in dir(evalue):
118+
value = pydoc.html.repr(getattr(evalue, name))
119+
exception.append('\n<br>%s%s&nbsp;=\n%s' % (indent, name, value))
120+
121+
import traceback
122+
plaintrace = ''.join(traceback.format_exception(etype, evalue, etb))
123+
124+
return head + ''.join(frames) + ''.join(exception) + '''
125+
126+
127+
<!-- The above is a description of an error that occurred in a Python program.
128+
It is formatted for display in a Web browser because it appears that
129+
we are running in a CGI environment. In case you are viewing this
130+
message outside of a Web browser, here is the original error traceback:
131+
132+
%s
133+
-->
134+
''' % plaintrace
135+
136+
class Hook:
137+
def __init__(self, display=1, logdir=None):
138+
self.display = display # send tracebacks to browser if true
139+
self.logdir = logdir # log tracebacks to files if not None
140+
141+
def __call__(self, etype, evalue, etb):
142+
"""This hook can replace sys.excepthook (for Python 2.1 or higher)."""
143+
self.handle((etype, evalue, etb))
144+
145+
def handle(self, info=None):
146+
import sys, os
147+
info = info or sys.exc_info()
148+
text = 0
149+
print reset()
150+
151+
try:
152+
doc = html(*info)
153+
except: # just in case something goes wrong
154+
import traceback
155+
doc = ''.join(traceback.format_exception(*info))
156+
text = 1
157+
158+
if self.display:
159+
if text:
160+
doc = doc.replace('&', '&amp;').replace('<', '&lt;')
161+
print '<pre>', doc, '</pre>'
162+
else:
163+
print doc
164+
else:
165+
print '<p>A problem occurred in a Python script.'
166+
167+
if self.logdir is not None:
168+
import tempfile
169+
name = tempfile.mktemp(['.html', '.txt'][text])
170+
path = os.path.join(self.logdir, os.path.basename(name))
171+
try:
172+
file = open(path, 'w')
173+
file.write(doc)
174+
file.close()
175+
print '<p>%s contains the description of this error.' % path
176+
except:
177+
print '<p>Tried to write to %s, but failed.' % path
178+
179+
handler = Hook().handle
180+
def enable(display=1, logdir=None):
181+
import sys
182+
sys.excepthook = Hook(display, logdir)

0 commit comments

Comments
 (0)