404 errors are not email-worthy.
[invirt/packages/invirt-web.git] / code / main.py
index 01d6e39..2b7cf07 100755 (executable)
@@ -117,15 +117,6 @@ class Defaults:
 
 DEFAULT_HEADERS = {'Content-Type': 'text/html'}
 
-def error(op, username, fields, err, emsg, traceback):
-    """Print an error page when a CodeError occurs"""
-    send_error_mail('xvm error on %s for %s: %s' % (op, username, err),
-                    'error on %s for %s: %s\n\n%s\n'
-                    % (op, username, err, emsg))
-    d = dict(op=op, user=username, fields=fields,
-             errorMessage=str(err), stderr=emsg, traceback=traceback)
-    return templates.error(searchList=[d])
-
 def invalidInput(op, username, fields, err, emsg):
     """Print an error page when an InvalidInput exception occurs"""
     d = dict(op=op, user=username, err_field=err.err_field,
@@ -475,7 +466,7 @@ console will suffer artifacts.
 
 def badOperation(u, s, e):
     """Function called when accessing an unknown URI."""
-    raise CodeError("Unknown operation")
+    return ({'Status': '404 Not Found'}, 'Invalid operation.')
 
 def infoDict(username, state, machine):
     """Get the variables used by info.tmpl."""
@@ -583,7 +574,7 @@ def unauthFront(_, _2, fields):
 
 def throwError(_, __, ___):
     """Throw an error, to test the error-tracing mechanisms."""
-    raise CodeError("test of the emergency broadcast system")
+    raise RuntimeError("test of the emergency broadcast system")
 
 mapping = dict(list=listVms,
                vnc=vnc,
@@ -616,6 +607,16 @@ Subject: %s
     p.stdin.close()
     p.wait()
 
+def show_error(op, username, fields, err, emsg, traceback):
+    """Print an error page when an exception occurs"""
+    d = dict(op=op, user=username, fields=fields,
+             errorMessage=str(err), stderr=emsg, traceback=traceback)
+    details = templates.error_raw(searchList=[d])
+    send_error_mail('xvm error on %s for %s: %s' % (op, username, err),
+                    details)
+    d['details'] = details
+    return templates.error(searchList=[d])
+
 def getUser(environ):
     """Return the current user based on the SSL environment variables"""
     email = environ.get('SSL_CLIENT_S_DN_Email', None)
@@ -661,7 +662,6 @@ class App:
             if isinstance(output, tuple):
                 new_headers, output = output
                 headers.update(new_headers)
-            print 'MOO2'
             e = revertStandardError()
             if e:
                 if isinstance(output, basestring):
@@ -675,35 +675,21 @@ class App:
             output_string =  str(output)
             checkpoint.checkpoint('output as a string')
         except Exception, err:
-            import traceback
             if not fields.has_key('js'):
-                if isinstance(err, CodeError):
-                    self.start('500 Internal Server Error', [('Content-Type', 'text/html')])
-                    e = revertStandardError()
-                    s = error(operation, self.username, fields,
-                              err, e, traceback.format_exc())
-                    yield str(s)
-                    return
                 if isinstance(err, InvalidInput):
                     self.start('200 OK', [('Content-Type', 'text/html')])
                     e = revertStandardError()
-                    yield str(invalidInput(operation, self.username, fields, err, e))
+                    yield str(invalidInput(operation, self.username, fields,
+                                           err, e))
                     return
-            self.start('500 Internal Server Error', [('Content-Type', 'text/plain')])
-            send_error_mail('xvm error: %s' % (err,),
-                            '%s\n' % (traceback.format_exc(),))
-            yield '''Uh-oh!  We experienced an error.
-Sorry about that.  We've gotten mail about it.
-
-Feel free to poke us at xvm@mit.edu if this bug is
-consistently biting you and we don't seem to be fixing it.
-
-In case you're curious, the gory details are here.
-----
-%s
-----
-%s
-----''' % (str(err), traceback.format_exc())
+            import traceback
+            self.start('500 Internal Server Error',
+                       [('Content-Type', 'text/html')])
+            e = revertStandardError()
+            s = show_error(operation, self.username, fields,
+                           err, e, traceback.format_exc())
+            yield str(s)
+            return
         status = headers.setdefault('Status', '200 OK')
         del headers['Status']
         self.start(status, headers.items())