예제 #1
0
    def __call__(self, environ, start_response):
        """
        This is straight copied from the original ErrorMiddleware code. Unfortunately they
        didnt separate out the actual exception handling into a function, so I must override...
        
        basically just adds the handle_async_exception() call
        """
        # We want to be careful about not sending headers twice,
        # and the content type that the app has committed to (if there
        # is an exception in the iterator body of the response)
        if environ.get('paste.throw_errors'):
            return self.application(environ, start_response)
        environ['paste.throw_errors'] = True

        try:
            __traceback_supplement__ = errormiddleware.Supplement, self, environ
            sr_checker = errormiddleware.ResponseStartChecker(start_response)
            app_iter = self.application(environ, sr_checker)
            return self.make_catching_iter(app_iter, environ, sr_checker)
        except:
            exc_info = sys.exc_info()
            try:
                
                count = get_debug_count(environ)
                base_path = Request(environ).application_url + '/_debug/'
                exc_data = collector.collect_exception(*exc_info)
                exc_data.view_url = base_path + str(count)
                if self.reporters:
                    for reporter in self.reporters:
                        reporter.report(exc_data)
                
                #is_async is set by the @ajax decorator
                if environ.get('is_async', None):
                    start_response('500 Internal Server Error',
                               [('content-type', 'application/json; charset=utf8')],
                               exc_info)
                    response = handle_async_exception(exc_info, environ)
                else:
                    start_response('500 Internal Server Error',
                               [('content-type', 'text/html; charset=utf8')],
                               exc_info)
                    # @@: it would be nice to deal with bad content types here
                    response = self.exception_handler(exc_info, environ)
                
                if isinstance(response, unicode):
                    response = response.encode('utf8')
                return [response]
            finally:
                # clean up locals...
                exc_info = None
예제 #2
0
    def respond(self, environ, start_response):
        """
        This is straight copied from the original ErrorMiddleware code. Unfortunately they
        didnt separate out the actual exception handling into a function, so I must override...
        
        basically just adds the handle_async_exception() call
        """
        req = Request(environ)
        if req.environ.get('paste.throw_errors'):
            return self.application(environ, start_response)
        base_path = req.application_url + '/_debug'
        req.environ['paste.throw_errors'] = True
        started = []
        
        def detect_start_response(status, headers, exc_info=None):
            try:
                return start_response(status, headers, exc_info)
            except:
                raise
            else:
                started.append(True)
        try:
            __traceback_supplement__ = errormiddleware.Supplement, self, environ
            app_iter = self.application(environ, detect_start_response)
            
            # Don't create a list from a paste.fileapp object 
            if isinstance(app_iter, fileapp._FileIter): 
                return app_iter
            
            try:
                return_iter = list(app_iter)
                return return_iter
            finally:
                if hasattr(app_iter, 'close'):
                    app_iter.close()
        except:
            exc_info = sys.exc_info()
            
            is_async = environ.get('is_async', None) == True
            content_type = is_async and 'application/json' or 'text/html'
            
            # Tell the Registry to save its StackedObjectProxies current state
            # for later restoration
            registry.restorer.save_registry_state(environ)

            count = get_debug_count(environ)
            view_uri = self.make_view_url(environ, base_path, count)
            if not started:
                headers = [('content-type', content_type)]
                headers.append(('X-Debug-URL', view_uri))
                start_response('500 Internal Server Error',
                               headers,
                               exc_info)
            
            environ['wsgi.errors'].write('Debug at: %s\n' % view_uri)

            exc_data = collector.collect_exception(*exc_info)
            exc_data.view_url = view_uri
            if self.reporters:
                for reporter in self.reporters:
                    reporter.report(exc_data)
            
            debug_info = DebugInfo(count, exc_info, exc_data, base_path,
                                   environ, view_uri, self.error_template,
                                   self.templating_formatters, self.head_html,
                                   self.footer_html, self.libraries)
            assert count not in self.debug_infos
            self.debug_infos[count] = debug_info

            if is_async:
                return [handle_async_exception(exc_info, environ, debug_info=debug_info)]
            
            # @@: it would be nice to deal with bad content types here
            return debug_info.content()