from __future__ import absolute_import
from mako import exceptions
import sys

class CatchMakoErrors(object):
    """Use Mako's error reporting faculties when appropriate."""
    
    def __init__(self, app):
        self.app = app
        
    def __call__(self, environ, start_response):
        try:
            return self.app(environ, start_response)
        except:
            if not environ.get('bazjunk.catch_errors',
                               lambda e: False)(environ):
                raise
            exc_info = sys.exc_info()
            tb = exc_info[2]
            lst = []
            while tb is not None:
                frame = tb.tb_frame
                code = frame.f_code
                lst.append(code.co_filename)
                if code.co_filename.endswith('_mak'):
                    break
                tb = tb.tb_next
            else:
                raise
            start_response('500 Internal Server Error',
                           [('content-type', 'text/html')],
                           exc_info)
            return [exceptions.html_error_template().render()]

    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:
            response = exceptions.html_error_template().render()
            if not error_on_close and hasattr(app_iter, 'close'):
                try:
                    app_iter.close()
                except:
                    close_response = self.exception_handler(
                        sys.exc_info(), environ)
                    response += (
                        '<hr noshade>Error in .close():<br>%s'
                        % close_response)
            yield response



