Index: trac/web/standalone.py
===================================================================
--- trac/web/standalone.py	(revision 2737)
+++ trac/web/standalone.py	(working copy)
@@ -21,10 +21,10 @@
 
 from trac import util, __version__
 from trac.env import open_environment
-from trac.web.api import Request
-from trac.web.cgi_frontend import TracFieldStorage
+from trac.web.api import Request, FieldStorage
 from trac.web.main import dispatch_request, get_environment, \
-                          send_pretty_error, send_project_index
+                          send_pretty_error, send_ugly_error, \
+                          send_project_index
 from trac.util import md5crypt
 
 import os
@@ -282,7 +282,12 @@
             self.server.send_project_index(req)
             return
 
-        env = get_environment(req, opts)
+        try:
+            env = get_environment(req, opts)
+        except Exception, e:
+            send_ugly_error(e, None, req)
+            return
+
         if not env:
             self.server.send_project_index(req)
             return
@@ -342,7 +347,7 @@
         headers = self.__handler.headers
         if self.method in ('GET', 'HEAD'):
             headers = None
-        self.args = TracFieldStorage(self.__handler.rfile, environ=environ,
+        self.args = FieldStorage(self.__handler.rfile, environ=environ,
                                      headers=headers, keep_blank_values=1)
 
     def read(self, size=None):
Index: trac/web/api.py
===================================================================
--- trac/web/api.py	(revision 2737)
+++ trac/web/api.py	(working copy)
@@ -18,6 +18,7 @@
 import mimetypes
 import os
 import urlparse
+import cgi
 
 from trac.core import Interface
 from trac.util import http_date
@@ -220,7 +221,31 @@
         """Write the given data to the response body."""
         raise NotImplementedError
 
+class FieldStorage(cgi.FieldStorage):
+    """
+    FieldStorage class with a few more functions to make it behave a bit
+    more like a dictionary
+    """
+    get = cgi.FieldStorage.getvalue
 
+    def __init__(self, *args, **kwargs):
+        cgi.FieldStorage.__init__(self, *args, **kwargs)
+        if not self.list:
+            self.list = []
+
+    def __setitem__(self, name, value):
+        if self.has_key(name):
+            del self[name]
+        self.list.append(cgi.MiniFieldStorage(name, value))
+
+    def __delitem__(self, name):
+        if not self.has_key(name):
+            raise KeyError(name)
+        self.list = filter(lambda x, name=name: x.name != name, self.list)
+
+    def read_single(self):
+        pass
+
 class IAuthenticator(Interface):
     """Extension point interface for components that can provide the name
     of the remote user."""
Index: trac/web/modpython_frontend.py
===================================================================
--- trac/web/modpython_frontend.py	(revision 2737)
+++ trac/web/modpython_frontend.py	(working copy)
@@ -20,6 +20,7 @@
 import mimetypes
 import os
 import re
+import sys
 
 try:
     from cStringIO import StringIO
@@ -29,9 +30,10 @@
 from mod_python import apache, util
 
 from trac.util import http_date
-from trac.web.api import Request, RequestDone
+from trac.web.api import Request, RequestDone, FieldStorage
 from trac.web.main import dispatch_request, get_environment, \
-                          send_pretty_error, send_project_index
+                          send_pretty_error, send_project_index, \
+                          send_ugly_error
 
 
 class ModPythonRequest(Request):
@@ -53,8 +55,16 @@
             self.scheme = 'https'
         if self.req.headers_in.has_key('Cookie'):
             self.incookie.load(self.req.headers_in['Cookie'])
-        self.args = FieldStorageWrapper(self.req)
 
+        # Fake normal CGI environment for cgi.FieldStorage
+        sys.argv = ['mod_python']
+        env = dict(self.req.subprocess_env.iteritems())
+        if 'Content-Type' in self.req.headers_in:
+            env['CONTENT_TYPE'] = self.req.headers_in['Content-Type']
+        if 'Content-Length' in self.req.headers_in:
+            env['CONTENT_LENGTH'] = self.req.headers_in['Content-Length']
+        self.args = FieldStorage(self.req, environ=env, keep_blank_values=1)
+
         # The root uri sometimes has to be explicitly specified because apache
         # sometimes get req.path_info wrong if many <alias> and <location> directives
         # are used.
@@ -196,7 +206,12 @@
             ('TracEnvParentDir', 'TRAC_ENV_PARENT_DIR'),
             ('TracEnvIndexTemplate', 'TRAC_ENV_INDEX_TEMPLATE'),
             ('TracTemplateVars', 'TRAC_TEMPLATE_VARS'))
-    env = get_environment(mpr, project_opts)
+    try:
+        env = get_environment(mpr, project_opts)
+    except Exception, e:
+        send_ugly_error(e, None, mpr)
+        return apache.OK
+
     if not env:
         send_project_index(mpr, project_opts)
         return apache.OK
Index: trac/web/cgi_frontend.py
===================================================================
--- trac/web/cgi_frontend.py	(revision 2737)
+++ trac/web/cgi_frontend.py	(working copy)
@@ -16,15 +16,15 @@
 # Author: Christopher Lenz <cmlenz@gmx.de>
 #         Matthew Good <trac@matt-good.net>
 
-import cgi
 import locale
 import os
 import re
 import sys
 
-from trac.web.api import Request
+from trac.web.api import Request, FieldStorage
 from trac.web.main import dispatch_request, get_environment, \
-                          send_pretty_error, send_project_index
+                          send_pretty_error, send_ugly_error, \
+                          send_project_index
 
 
 class CGIRequest(Request):
@@ -61,7 +61,7 @@
 
 
     def _getFieldStorage(self):
-        return TracFieldStorage(self.__input, environ=self.__environ,
+        return FieldStorage(self.__input, environ=self.__environ,
                                 keep_blank_values=1)
 
     def read(self, len):
@@ -83,24 +83,6 @@
         self.write('\r\n')
 
 
-class TracFieldStorage(cgi.FieldStorage):
-    """
-    FieldStorage class with a few more functions to make it behave a bit
-    more like a dictionary
-    """
-    get = cgi.FieldStorage.getvalue
-
-    def __setitem__(self, name, value):
-        if self.has_key(name):
-            del self[name]
-        self.list.append(cgi.MiniFieldStorage(name, value))
-
-    def __delitem__(self, name):
-        if not self.has_key(name):
-            raise KeyError(name)
-        self.list = filter(lambda x, name=name: x.name != name, self.list)
-
-
 def run():
     try: # Make FreeBSD use blocking I/O like other platforms
         import fcntl
@@ -121,7 +103,11 @@
     locale.setlocale(locale.LC_ALL, '')
 
     req = CGIRequest()
-    env = get_environment(req, os.environ, threaded=False)
+    try:
+        env = get_environment(req, os.environ, threaded=False)
+    except Exception, e:
+        send_ugly_error(e, None, req)
+        return
 
     if not env:
         send_project_index(req, os.environ)
Index: trac/web/main.py
===================================================================
--- trac/web/main.py	(revision 2737)
+++ trac/web/main.py	(working copy)
@@ -193,6 +193,25 @@
             else:
                 hdf['args.%s' % arg] = req.args[arg].value
 
+def send_ugly_error(e, env, req, tb = None):
+    if not tb:
+        import traceback
+        import StringIO
+        tb = StringIO.StringIO()
+        traceback.print_exc(file=tb)
+
+    try:
+        req.send_response(500)
+        req.send_header('Content-Type', 'text/plain')
+        req.end_headers()
+        req.write('Oops...\n\nTrac detected an internal error:\n\n')
+        req.write(str(e))
+        req.write('\n')
+        req.write(tb.getvalue())
+    except IOError:
+        # Cannot send response, but the error has hopefully been logged
+        pass
+
 def send_pretty_error(e, env, req=None):
     """Send a "pretty" HTML error page to the client."""
     import traceback
@@ -243,17 +262,7 @@
         if env and env.log:
             env.log.error('Failed to render pretty error page: %s', e2,
                           exc_info=True)
-        try:
-            req.send_response(500)
-            req.send_header('Content-Type', 'text/plain')
-            req.end_headers()
-            req.write('Oops...\n\nTrac detected an internal error:\n\n')
-            req.write(str(e))
-            req.write('\n')
-            req.write(tb.getvalue())
-        except IOError:
-            # Cannot send response, but the error has hopefully been logged
-            pass
+        send_ugly_error(e, env, req, tb)
 
 def send_project_index(req, options, env_paths=None):
     from trac.web.clearsilver import HDFWrapper
Index: trac/web/fcgi_frontend.py
===================================================================
--- trac/web/fcgi_frontend.py	(revision 2737)
+++ trac/web/fcgi_frontend.py	(working copy)
@@ -30,13 +30,17 @@
 
 def _handler(_req):
     req = CGIRequest(_req.params, _req.stdin, _req.stdout)
-    env = get_environment(req, os.environ)
+    try:
+        env = get_environment(req, os.environ)
+    except Exception, e:
+        send_ugly_error(e, None, req)
+        return _fcgi.FCGI_REQUEST_COMPLETE, 0
 
     if not env:
         send_project_index(req, os.environ)
         return _fcgi.FCGI_REQUEST_COMPLETE, 0
 
-    try:  
+    try:
         dispatch_request(req.path_info, req, env)
     except Exception, e:
         send_pretty_error(e, env, req)

