78
84
just used to catch exceptions.
79
85
Takes both an IVLE request and an Apache req.
87
# Hack? Try and get the user login early just in case we throw an error
88
# (most likely 404) to stop us seeing not logged in even when we are.
89
if not req.publicmode:
90
req.user = login.get_user_details(req)
81
92
# Check req.app to see if it is valid. 404 if not.
82
93
if req.app is not None and req.app not in conf.apps.app_url:
83
94
# Maybe it is a special app!
87
98
req.throw_error(Request.HTTP_NOT_FOUND,
88
99
"There is no application called %s." % repr(req.app))
90
# Special handling for public mode - just call public app and get out
101
# Special handling for public mode - only allow the public app, call it
91
103
# NOTE: This will not behave correctly if the public app uses
92
104
# write_html_head_foot, but "serve" does not.
93
105
if req.publicmode:
106
if req.app != conf.apps.public_app:
107
req.throw_error(Request.HTTP_FORBIDDEN,
108
"This application is not available on the public site.")
94
109
app = conf.apps.app_url[conf.apps.public_app]
95
110
apps.call_app(app.dir, req)
144
159
# When done, write out the HTML footer if the app has requested it
145
160
if req.write_html_head_foot:
161
# Show the console if required
162
if logged_in and app.useconsole:
163
plugins.console.present(req, windowpane=True)
146
164
html.write_html_foot(req)
148
166
# Note: Apache will not write custom HTML error messages here.
170
188
the IVLE request is created.
172
190
req.content_type = "text/html"
173
admin_email = apache._server.server_admin
191
logfile = os.path.join(conf.conf.log_path, 'ivle_error.log')
193
# For some reason, some versions of mod_python have "_server" instead of
194
# "main_server". So we check for both.
196
admin_email = apache.main_server.server_admin
197
except AttributeError:
199
admin_email = apache._server.server_admin
200
except AttributeError:
175
203
httpcode = exc_value.httpcode
176
204
req.status = httpcode
177
205
except AttributeError:
179
207
req.status = apache.HTTP_INTERNAL_SERVER_ERROR
209
login = req.user.login
210
except AttributeError:
215
logging.basicConfig(level=logging.INFO,
216
format='%(asctime)s %(levelname)s: ' +
217
'(HTTP: ' + str(req.status) +
218
', Ref: ' + str(login) + '@' +
219
str(socket.gethostname()) + str(req.uri) +
225
logging.debug('Logging Unhandled Exception')
180
227
# We handle 3 types of error.
181
228
# IVLEErrors with 4xx response codes (client error).
182
229
# IVLEErrors with 5xx response codes (handled server error).
190
237
# IVLEErrors with 4xx response codes are client errors.
191
238
# Therefore, these have a "nice" response (we even coat it in the IVLE
192
239
# HTML wrappers).
193
241
req.write_html_head_foot = True
194
242
req.write('<div id="ivle_padding">\n')
201
249
if exc_value.message is not None:
202
250
msg = exc_value.message
203
251
if codename is not None:
204
req.write("<h1>Error: %s</h1>\n" % codename)
252
req.write("<h1>Error: %s</h1>\n" % cgi.escape(codename))
206
254
req.write("<h1>Error</h1>\n")
207
255
if msg is not None:
208
req.write("<p>%s</p>\n" % msg)
256
req.write("<p>%s</p>\n" % cgi.escape(msg))
210
258
req.write("<p>An unknown error occured.</p>\n")
261
logging.info(str(msg))
211
263
req.write("<p>(HTTP error code %d)</p>\n" % httpcode)
265
req.write("<p>Warning: Could not open Error Log: '%s'</p>\n"
266
%cgi.escape(logfile))
212
267
req.write('</div>\n')
214
269
# A "bad" error message. We shouldn't get here unless IVLE
218
273
# If this is a non-4xx IVLEError, get the message and httpcode and
219
274
# make the error message a bit nicer (but still include the
222
codename, msg = req.get_http_codename(httpcode)
223
except AttributeError:
224
codename, msg = None, None
225
# Override the default message with the supplied one,
227
if hasattr(exc_value, 'message') and exc_value.message is not None:
228
msg = exc_value.message
276
# We also need to special-case IVLEJailError, as we can get another
277
# almost-exception out of it.
279
codename, msg = None, None
281
if exc_type is util.IVLEJailError:
282
msg = exc_value.type_str + ": " + exc_value.message
283
tb = 'Exception information extracted from IVLEJailError:\n'
284
tb += urllib.unquote(exc_value.info)
287
codename, msg = req.get_http_codename(httpcode)
288
except AttributeError:
290
# Override the default message with the supplied one,
292
if hasattr(exc_value, 'message') and exc_value.message is not None:
293
msg = exc_value.message
294
# Prepend the exception type
295
if exc_type != util.IVLEError:
296
msg = exc_type.__name__ + ": " + msg
298
tb = ''.join(traceback.format_exception(exc_type, exc_value,
302
logging.error('%s\n%s'%(str(msg), tb))
230
304
req.write("""<html>
231
305
<head><title>IVLE Internal Server Error</title></head>
233
307
<h1>IVLE Internal Server Error""")
234
308
if (codename is not None
235
309
and httpcode != apache.HTTP_INTERNAL_SERVER_ERROR):
236
req.write(": %s" % codename)
310
req.write(": %s" % cgi.escape(codename))
237
311
req.write("""</h1>
238
312
<p>An error has occured which is the fault of the IVLE developers or
239
313
administration.</p>
241
315
if msg is not None:
242
req.write("<p>%s</p>\n" % msg)
316
req.write("<p>%s</p>\n" % cgi.escape(msg))
243
317
if httpcode is not None:
244
318
req.write("<p>(HTTP error code %d)</p>\n" % httpcode)
246
320
<p>Please report this to <a href="mailto:%s">%s</a> (the system
247
321
administrator). Include the following information:</p>
248
""" % (admin_email, admin_email))
322
""" % (cgi.escape(admin_email), cgi.escape(admin_email)))
250
tb_print = cStringIO.StringIO()
251
traceback.print_exception(exc_type, exc_value, exc_traceback,
254
req.write(tb_print.getvalue())
255
req.write("</pre>\n</body>\n")
324
req.write("<pre>\n%s\n</pre>\n"%cgi.escape(tb))
326
req.write("<p>Warning: Could not open Error Log: '%s'</p>\n"
327
%cgi.escape(logfile))