42
42
from ivle import util
44
44
from ivle.dispatch.request import Request
45
45
import ivle.webapp.security
46
46
from ivle.webapp.base.plugins import ViewPlugin, PublicViewPlugin
47
from ivle.webapp.errors import HTTPError, Unauthorized
49
def generate_route_mapper(view_plugins, attr):
47
from ivle.webapp.base.xhtml import XHTMLView, XHTMLErrorView
48
from ivle.webapp.errors import HTTPError, Unauthorized, NotFound
50
config = ivle.config.Config()
52
def generate_router(view_plugins, attr):
51
54
Build a Mapper object for doing URL matching using 'routes', based on the
52
55
given plugin registry.
70
73
@param apachereq: An Apache request object.
72
75
# Make the request object into an IVLE request which can be given to views
73
req = Request(apachereq)
76
req = Request(apachereq, config)
75
78
# Hack? Try and get the user login early just in case we throw an error
76
79
# (most likely 404) to stop us seeing not logged in even when we are.
81
84
if user and user.valid:
84
conf = ivle.config.Config()
88
req.mapper = generate_route_mapper(conf.plugin_index[PublicViewPlugin],
88
req.mapper = generate_router(config.plugin_index[PublicViewPlugin],
91
req.mapper = generate_route_mapper(conf.plugin_index[ViewPlugin],
91
req.mapper = generate_router(config.plugin_index[ViewPlugin], 'urls')
94
93
matchdict = req.mapper.match(req.uri)
95
94
if matchdict is not None:
116
115
if hasattr(viewcls, 'get_error_view'):
117
116
errviewcls = viewcls.get_error_view(e)
118
errviewcls = XHTMLView.get_error_view(e)
122
121
errview = errviewcls(req, e)
129
except mod_python.apache.SERVER_RETURN:
130
# A mod_python-specific Apache error.
131
# XXX: We need to raise these because req.throw_error() uses them.
132
# Remove this after Google Code issue 117 is fixed.
130
134
except Exception, e:
131
135
# A non-HTTPError appeared. We have an unknown exception. Panic.
132
136
handle_unknown_exception(req, *sys.exc_info())
135
139
req.store.commit()
138
return req.HTTP_NOT_FOUND # TODO: Prettify.
142
XHTMLErrorView(req, NotFound()).render(req)
140
145
def handle_unknown_exception(req, exc_type, exc_value, exc_traceback):
148
153
the IVLE request is created.
150
155
req.content_type = "text/html"
151
logfile = os.path.join(ivle.conf.log_path, 'ivle_error.log')
156
logfile = os.path.join(config['paths']['logs'], 'ivle_error.log')
154
httpcode = exc_value.httpcode
155
req.status = httpcode
156
except AttributeError:
158
req.status = mod_python.apache.HTTP_INTERNAL_SERVER_ERROR
158
req.status = mod_python.apache.HTTP_INTERNAL_SERVER_ERROR
160
161
publicmode = req.publicmode
161
162
except AttributeError:
188
185
# misbehaves (which is currently very easy, if things aren't set up
190
187
# Write the traceback.
191
# If this is a non-4xx IVLEError, get the message and httpcode and
192
# make the error message a bit nicer (but still include the
194
# We also need to special-case IVLEJailError, as we can get another
189
# We need to special-case IVLEJailError, as we can get another
195
190
# almost-exception out of it.
197
codename, msg = None, None
199
191
if exc_type is util.IVLEJailError:
200
msg = exc_value.type_str + ": " + exc_value.message
201
192
tb = 'Exception information extracted from IVLEJailError:\n'
202
193
tb += urllib.unquote(exc_value.info)
205
codename, msg = req.get_http_codename(httpcode)
206
except AttributeError:
209
195
tb = ''.join(traceback.format_exception(exc_type, exc_value,
212
logging.error('%s\n%s'%(str(msg), tb))
198
logging.error('\n' + tb)
214
200
# Error messages are only displayed is the user is NOT a student,
215
201
# or if there has been a problem logging the error message
216
show_errors = (not publicmode) and ((login and \
217
str(role) != "student") or logfail)
202
show_errors = (not publicmode) and ((login and req.user.admin) or logfail)
218
203
req.write("""<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
219
204
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
220
205
<html xmlns="http://www.w3.org/1999/xhtml">
221
206
<head><title>IVLE Internal Server Error</title></head>
223
<h1>IVLE Internal Server Error""")
225
if codename is not None and \
226
httpcode != mod_python.apache.HTTP_INTERNAL_SERVER_ERROR:
227
req.write(": %s" % cgi.escape(codename))
208
<h1>IVLE Internal Server Error</h1>
230
209
<p>An error has occured which is the fault of the IVLE developers or
231
210
administrators. """)
238
217
req.write("</p>")
242
req.write("<p>%s</p>\n" % cgi.escape(msg))
243
if httpcode is not None:
244
req.write("<p>(HTTP error code %d)</p>\n" % httpcode)
245
220
req.write("<h2>Debugging information</h2>")
247
221
req.write("<pre>\n%s\n</pre>\n"%cgi.escape(tb))
248
222
req.write("</body></html>")