~ubuntu-branches/ubuntu/natty/moin/natty-updates

« back to all changes in this revision

Viewing changes to MoinMoin/failure.py

  • Committer: Bazaar Package Importer
  • Author(s): Jonas Smedegaard
  • Date: 2008-06-22 21:17:13 UTC
  • mfrom: (0.9.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20080622211713-fpo2zrq3s5dfecxg
Tags: 1.7.0-3
Simplify /etc/moin/wikilist format: "USER URL" (drop unneeded middle
CONFIG_DIR that was wrongly advertised as DATA_DIR).  Make
moin-mass-migrate handle both formats and warn about deprecation of
the old one.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
# -*- coding: iso-8859-1 -*-
2
2
""" MoinMoin failure
3
3
 
4
 
Handle fatal errors by showing a message and debugging information.
 
4
    Handle fatal errors by showing a message and debugging information.
5
5
 
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.
8
8
"""
9
9
import sys, os
 
10
 
 
11
from MoinMoin import log
 
12
logging = log.getLogger(__name__)
 
13
 
10
14
from MoinMoin.support import cgitb
 
15
from MoinMoin.error import ConfigurationError
 
16
from traceback import extract_tb
11
17
 
12
18
 
13
19
class View(cgitb.View):
14
20
    """ Display an error message and debugging information
15
 
    
 
21
 
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
22
 
     
 
28
 
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.
25
31
 
26
32
    cgitb was refactored to be easy to customize by applications
27
33
    developers. This moin specific subclass is an example.
28
34
    """
29
35
    debugInfoID = 'debug-info'
30
 
    
 
36
 
31
37
    def formatContent(self):
32
38
        content = (
33
39
            self.script(),
39
45
            self.formatTextTraceback()
40
46
            )
41
47
        return ''.join(content)
42
 
    
 
48
 
43
49
    def script(self):
44
50
        return '''
45
51
<script type="text/javascript">
53
59
 
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;}
58
64
"""
59
65
 
60
66
    def formatMessage(self):
61
67
        """ handle multiple paragraphs messages and add general help """
62
68
        f = self.formatter
63
 
        text = [self.formatExceptionMessage(self.info),
 
69
        text = [self.formatExceptionMessage(self.info)]
 
70
 
 
71
        if self.info[0] == ConfigurationError:
 
72
            tbt = extract_tb(self.info[1].exceptions()[-1][2])[-1]
 
73
            text.append(
 
74
                f.paragraph('Error in your configuration file "%s"'
 
75
                            ' around line %d.' % tbt[:2]))
 
76
        else:
 
77
            text.append(
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)
67
81
 
68
82
    def formatButtons(self):
69
83
        """ Add 'buttons' to the error dialog """
70
84
        f = self.formatter
71
 
        buttons = [f.link('javascript:toggleDebugInfo()', 
72
 
                          'Show debugging information'),
73
 
                   f.link('http://moinmoin.wikiwikiweb.de/MoinMoinBugs', 
74
 
                          'Report bug'),
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:
 
88
            buttons.append(
 
89
                   f.link('http://moinmo.in/MoinMoinBugs',
 
90
                          'Report bug'))
 
91
            buttons.append(
 
92
                   f.link('http://moinmo.in/FrontPage',
 
93
                          'Visit MoinMoin wiki'))
77
94
        return f.list(buttons, {'class': 'buttons'})
78
 
    
 
95
 
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)
86
103
 
87
104
    def debugInfoHideScript(self):
94
111
 
95
112
    def formatTraceback(self):
96
113
        return self.formatAllTracebacks(self.formatOneTraceback)
97
 
        
 
114
 
98
115
    def formatTextTraceback(self):
99
116
        template = self.textTracebackTemplate()
100
 
        return template % self.formatAllTracebacks(self.formatOneTextTraceback)        
 
117
        return template % self.formatAllTracebacks(self.formatOneTextTraceback)
101
118
 
102
119
    def formatAllTracebacks(self, formatFuction):
103
120
        """ Format multiple tracebacks using formatFunction """
104
121
        tracebacks = []
105
 
        for type, value, tb in self.exceptions():
106
 
            if type is None: 
 
122
        for ttype, tvalue, tb in self.exceptions():
 
123
            if ttype is None:
107
124
                break
108
 
            tracebacks.append(formatFuction((type, value, tb)))
 
125
            tracebacks.append(formatFuction((ttype, tvalue, tb)))
109
126
            del tb
110
127
        return ''.join(tracebacks)
111
128
 
130
147
        return text
131
148
 
132
149
 
133
 
def handle(request):
 
150
def handle(request, err):
134
151
    """ Handle failures
135
 
    
 
152
 
136
153
    Display fancy error view, or fallback to simple text traceback
137
154
    """
 
155
    if 'MOIN_DEBUG' in os.environ:
 
156
        raise err
 
157
 
138
158
    savedError = sys.exc_info()
 
159
    logging.exception('An exception occured.')
139
160
    try:
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
 
164
        display = True
 
165
        logdir = None
 
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)
146
171
        handler.handle()
147
172
    except:
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')
153
178
 
154
 
        
 
179
 
155
180
def printTextException(request, info=None):
156
181
    """ Simple text exception that should never fail
157
 
    
 
182
 
158
183
    Print all exceptions in a composite error.
159
184
    """
160
185
    import traceback