# Based on paste.cgitb_catcher, which is available under the MIT licens. # http://www.opensource.org/licenses/mit-license.php import sys, traceback from bazjunk import email class EmailErrors(object): def __init__(self, app, subject_prefix, **email_args): self.app = app self.subject_prefix = subject_prefix self.email_args = email_args def __call__(self, environ, start_response): try: app_iter = self.app(environ, start_response) return self.catching_iter(app_iter, environ) except: exc_info = sys.exc_info() self.exception_handler(exc_info, environ) raise def catching_iter(self, app_iter, environ): if not app_iter: raise StopIteration error_on_close = False try: for v in app_iter: yield v if hasattr(app_iter, 'close'): error_on_close = True app_iter.close() except GeneratorExit: if not error_on_close and hasattr(app_iter, 'close'): app_iter.close() except: self.exception_handler(sys.exc_info(), environ, ' in iter') if not error_on_close and hasattr(app_iter, 'close'): try: app_iter.close() except: self.exception_handler(sys.exc_info(), environ, ' in .close()') raise def exception_handler(self, exc_info, environ, detail=''): type, value, tb = exc_info msg = ''.join(traceback.format_exception(type, value, tb)) msg += '\n\n' msg += 'Environ:\n' for k in sorted(environ): msg += ' %s = %s\n' % (k, repr(environ[k])) subject = "%s%s: %s" % (self.subject_prefix, detail, value) email.send(msg, subject, **self.email_args)