[albatross-users] Albatross development preview 1.2-dev-20040114

Michael C. Neel neel at mediapulse.com
Fri Jan 16 10:54:32 EST 2004


> Because there are deployed apps out there, I'm thinking of making
> Application.run() return 0 unconditionally, and applying a patch like
> this to apacheapp.py:
> 
<snip>

This only has an effect in mod_python 3.x, 2.x ignores this and I've
been unable to come up with a solution for traceback errors to be status
500 on Apache 1.3.  We are okay atm, because on a live site we'd never
show that information anyway, and use a traceback.html.  So for now we
use apache ErrorDocument directives on the live side of things, and even
has the upshot of having al- tags in the error page, which you can't do
for traceback.html (which is to be expected).

One small plus is setting req.status in 2.x has zero effect, so need to
have code to check versions before applying.

Just for fun and thoughts, here is the current class we use for the
cusomt error handling.  It's a little tied to the way we pass in some
extra members to req, such as req.debug and req.config.  Also, I wasn't
able to get everything I wanted out of req itself, so it's also
mod_python centric.

Mike


class MPErrorHandlingApp(albatross.SimpleApp):
    '''App class to control traceback error messages.
       If req.debug is true, display the normal traceback information.
       If req.debug is false, it will set the status to 404 or 500 which
is returned to apache
       If req.config has a key 'developer_email' it will email the
traceback and other
        details to the developer on an error.

       Currently this class relies on the mod_python request class.'''

    email_template='''To: %(dev_email)s
From: Traceback <webserver at webserver.com>
Subject: [TRACEBACK] - %(website)s

%(error)s
Connection Details:
  Server:        %(website)s:%(port)s
  Request:       %(request)s
  Client IP/DNS: %(client_dns)s
  Date/Time:     %(timestamp)s

Client Headers:
%(headers)s

%(htmlexc)s

%(pyexc)s

Form Data:
%(data)s

'''

    def handle_exception(self, ctx, req):

        etype, value, tb = sys.exc_info()
        pyexc = traceback.format_exception(etype, value, tb)
        htmlexc = []
        htmlexc.append('Template traceback (most recent call last):\n')
        for tup in self.template_traceback(tb):
            htmlexc.append('  File "%s", line %s, in %s\n' % tup)
            line = string.rstrip(linecache.getline(tup[0], tup[1]))
            if line:
                htmlexc.append(line + '\n')

        if req.debug:
            req.write_header('Content-Type', 'text/html')
            req.end_headers()
            req.write_content('<pre>')
            req.write_content(''.join(map(lambda x:
albatross.tags.escape(x), htmlexc)))
            req.write_content('\n\n')
            req.write_content(''.join(map(lambda x:
albatross.tags.escape(x), pyexc)))
            req.write_content('</pre>')
        else:
            if pyexc[-1].find("TemplateLoadError:") >= 0:
                req.set_status(404)
            else:
                req.set_status(500)

        if req.config.has_key('developer_email') and
pyexc[-1].find("TemplateLoadError:") == -1:
            details = { 'dev_email': req.config['developer_email'],
                        'website': req.get_servername(),
                        'htmlexc': ''.join(htmlexc),
                        'pyexc': ''.join(pyexc),
                        'headers': '',
                        'data': '',
                        'request': req._Request__req.unparsed_uri,
                        'client_dns':
req._Request__req.get_remote_host(),
                        'timestamp': time.asctime(),
                        'port': req._Request__req.server.port,
                        'error': pyexc[-1] }

            for field in req.field_names():
                details['data'] = details['data'] + '  %s: %s\n' %
(field, req.field_value(field))

            for header in req._Request__req.headers_in.keys():
                details['headers'] = details['headers'] + '  %s: %s\n' %
(header,
 
req._Request__req.headers_in[header])

            mailserver = smtplib.SMTP("localhost")
            mailserver.sendmail(details['dev_email'],
[details['dev_email'],], self.email_template % details)
            mailserver.quit()




More information about the Albatross-users mailing list