1
1
# -*- coding: iso-8859-1 -*-
4
Handle fatal errors by showing a message and debugging information.
4
Handle fatal errors by showing a message and debugging information.
6
@copyright: 2004, 2005 by Nir Soffer <nirs@freeshell.org>
7
@license: GNU GPL, see COPYING for details.
6
@copyright: 2004-2005 Nir Soffer <nirs@freeshell.org>
7
@license: GNU GPL, see COPYING for details.
11
from MoinMoin import log
12
logging = log.getLogger(__name__)
10
14
from MoinMoin.support import cgitb
15
from MoinMoin.error import ConfigurationError
16
from traceback import extract_tb
13
19
class View(cgitb.View):
14
20
""" Display an error message and debugging information
16
22
Additions to cgitb.View:
17
23
- Multiple tracebacks support
18
24
- Debugging information is shown only in debug mode
19
25
- Moin application information
20
26
- General help text and links
21
27
- Handle multiple paragraphs in exception message
23
29
cgitb is heavily modified cgitb, but fully backward compatible with
24
the standard cgitb. It should not contain any moin specific code.
30
the standard cgitb. It should not contain any moin specific code.
26
32
cgitb was refactored to be easy to customize by applications
27
33
developers. This moin specific subclass is an example.
29
35
debugInfoID = 'debug-info'
31
37
def formatContent(self):
54
60
def stylesheet(self):
55
61
return cgitb.View.stylesheet(self) + """
56
.cgitb .buttons {margin: 0.5em 0; padding: 5px 10px;}
62
.cgitb .buttons {margin: 0.5em 0; padding: 5px 10px;}
57
63
.cgitb .buttons li {display: inline; margin: 0; padding: 0 0.25em;}
60
66
def formatMessage(self):
61
67
""" handle multiple paragraphs messages and add general help """
63
text = [self.formatExceptionMessage(self.info),
69
text = [self.formatExceptionMessage(self.info)]
71
if self.info[0] == ConfigurationError:
72
tbt = extract_tb(self.info[1].exceptions()[-1][2])[-1]
74
f.paragraph('Error in your configuration file "%s"'
75
' around line %d.' % tbt[:2]))
64
78
f.paragraph("If you want to report a bug, please save "
65
"this page and attach it to your bug report."),]
79
"this page and attach it to your bug report."))
66
80
return ''.join(text)
68
82
def formatButtons(self):
69
83
""" Add 'buttons' to the error dialog """
71
buttons = [f.link('javascript:toggleDebugInfo()',
72
'Show debugging information'),
73
f.link('http://moinmoin.wikiwikiweb.de/MoinMoinBugs',
75
f.link('http://moinmoin.wikiwikiweb.de/FrontPage',
76
'Visit MoinMoin wiki'),]
85
buttons = [f.link('javascript:toggleDebugInfo()',
86
'Show debugging information')]
87
if self.info[0] != ConfigurationError:
89
f.link('http://moinmo.in/MoinMoinBugs',
92
f.link('http://moinmo.in/FrontPage',
93
'Visit MoinMoin wiki'))
77
94
return f.list(buttons, {'class': 'buttons'})
79
96
def formatDebugInfo(self):
80
97
""" Put debugging information in a hidden div """
81
98
attributes = {'id': self.debugInfoID}
82
99
info = [self.debugInfoHideScript(),
83
100
self.formatTraceback(),
84
self.formatSystemDetails(),]
101
self.formatSystemDetails(), ]
85
102
return self.formatter.section(''.join(info), attributes)
87
104
def debugInfoHideScript(self):
95
112
def formatTraceback(self):
96
113
return self.formatAllTracebacks(self.formatOneTraceback)
98
115
def formatTextTraceback(self):
99
116
template = self.textTracebackTemplate()
100
return template % self.formatAllTracebacks(self.formatOneTextTraceback)
117
return template % self.formatAllTracebacks(self.formatOneTextTraceback)
102
119
def formatAllTracebacks(self, formatFuction):
103
120
""" Format multiple tracebacks using formatFunction """
105
for type, value, tb in self.exceptions():
122
for ttype, tvalue, tb in self.exceptions():
108
tracebacks.append(formatFuction((type, value, tb)))
125
tracebacks.append(formatFuction((ttype, tvalue, tb)))
110
127
return ''.join(tracebacks)
150
def handle(request, err):
134
151
""" Handle failures
136
153
Display fancy error view, or fallback to simple text traceback
155
if 'MOIN_DEBUG' in os.environ:
138
158
savedError = sys.exc_info()
159
logging.exception('An exception occured.')
140
debug = ('debug' in getattr(request, 'form', {}) or
141
'MOIN_DEBUG' in os.environ)
142
handler = cgitb.Hook(file=request,
143
display=request.cfg.traceback_show,
144
logdir=request.cfg.traceback_log_dir,
161
debug = 'debug' in getattr(request, 'form', {})
162
# default to True here to allow an admin setting up the wiki
163
# to see the errors made in the configuration file
166
if hasattr(request, 'cfg'):
167
display = request.cfg.traceback_show
168
logdir = request.cfg.traceback_log_dir
169
handler = cgitb.Hook(file=request, display=display, logdir=logdir,
145
170
viewClass=View, debug=debug)
148
173
request.write('<pre>\n')
149
174
printTextException(request, savedError)
150
175
request.write('\nAdditionally cgitb raised this exception:\n')
151
printTextException(request)
176
printTextException(request)
152
177
request.write('</pre>\n')
155
180
def printTextException(request, info=None):
156
181
""" Simple text exception that should never fail
158
183
Print all exceptions in a composite error.