Esempio n. 1
0
def test_logger():
    fn = setup_file('test_logger.log')
    rep = LogReporter(
        filename=fn,
        show_hidden_frames=False)
    try:
        int('a')
    except:
        exc_data = collector.collect_exception(*sys.exc_info())
    else:
        assert 0
    rep.report(exc_data)
    content = open(fn).read()
    assert len(content.splitlines()) == 4
    assert 'ValueError' in content
    assert 'int' in content
    assert 'test_reporter.py' in content
    assert 'test_logger' in content
    
    try:
        1 / 0
    except:
        exc_data = collector.collect_exception(*sys.exc_info())
    else:
        assert 0
    rep.report(exc_data)
    content = open(fn).read()
    print content
    assert len(content.splitlines()) == 8
    assert 'ZeroDivisionError' in content
Esempio n. 2
0
def test_file():
    fn = setup_file('test_file.log')
    f = open(fn, 'w')
    rep = FileReporter(file=f, show_hidden_frames=False)

    try:
        int('a')
    except:
        exc_data = collector.collect_exception(*sys.exc_info())
    else:
        assert 0
    rep.report(exc_data)
    f.flush()
    content = open(fn).read()
    assert len(content.splitlines()) == 4
    assert 'ValueError' in content
    assert 'int' in content
    assert 'test_reporter.py' in content
    assert 'test_file' in content

    try:
        1 / 0
    except:
        exc_data = collector.collect_exception(*sys.exc_info())
    else:
        assert 0
    rep.report(exc_data)
    f.flush()
    content = open(fn).read()
    print content
    assert len(content.splitlines()) == 8
    assert 'ZeroDivisionError' in content
Esempio n. 3
0
def test_file():
    fn = setup_file("test_file.log")
    f = open(fn, "w")
    rep = FileReporter(file=f, show_hidden_frames=False)

    try:
        int("a")
    except:
        exc_data = collector.collect_exception(*sys.exc_info())
    else:
        assert 0
    rep.report(exc_data)
    f.flush()
    content = open(fn).read()
    assert len(content.splitlines()) == 4
    assert "ValueError" in content
    assert "int" in content
    assert "test_reporter.py" in content
    assert "test_file" in content

    try:
        1 / 0
    except:
        exc_data = collector.collect_exception(*sys.exc_info())
    else:
        assert 0
    rep.report(exc_data)
    f.flush()
    content = open(fn).read()
    print content
    assert len(content.splitlines()) == 8
    assert "ZeroDivisionError" in content
Esempio n. 4
0
def capture_exception(event_type="Exception",
                      exc_info=None,
                      level=logging.ERROR,
                      tags=None,
                      extra=None):
    """Capture the current exception"""
    exc_info = exc_info or sys.exc_info()

    # Ensure that no matter what happens, we always del the exc_info
    try:
        collected = collect_exception(*exc_info)

        # Check to see if this hash has been reported past the threshold
        # TODO: Use this in the future
        # cur_sec = int(time.time())
        # capture_key = '%s %s' % (hash, cur_sec)

        frames = []
        update_frame_visibility(collected.frames)
        for frame in collected.frames:
            fdata = {
                'id': frame.tbid,
                'filename': frame.filename,
                'module': frame.modname or '?',
                'function': frame.name or '?',
                'lineno': frame.lineno,
                'vars': frame.locals,
                'context_line': frame.get_source_line(),
                'with_context': frame.get_source_line(context=5),
                'visible': frame.visible,
            }
            frames.append(fdata)

        data = {
            'value': transform(collected.exception_value),
            'type': collected.exception_type,
            'message': ''.join(collected.exception_formatted),
            'level': level,
            'frames': frames,
            'traceback': ''.join(traceback.format_exception(*exc_info)),
        }
        modules = [frame['module'] for frame in data['frames']]
        data['versions'] = lookup_versions(modules)
        return capture(event_type,
                       tags=tags,
                       data=data,
                       extra=extra,
                       hash=collected.identification_code)
    finally:
        del exc_info
        if 'collected' in locals():
            del collected
Esempio n. 5
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
Esempio n. 6
0
def capture_exception(event_type="Exception", exc_info=None, 
                      level=logging.ERROR, tags=None, extra=None):
    """Capture the current exception"""
    exc_info = exc_info or sys.exc_info()
    
    # Ensure that no matter what happens, we always del the exc_info
    try:
        collected = collect_exception(*exc_info)

        # Check to see if this hash has been reported past the threshold
        # TODO: Use this in the future
        # cur_sec = int(time.time())
        # capture_key = '%s %s' % (hash, cur_sec)
    
        frames = []
        update_frame_visibility(collected.frames)
        for frame in collected.frames:
            fdata = {
                'id': frame.tbid,
                'filename': frame.filename,
                'module': frame.modname or '?',
                'function': frame.name or '?',
                'lineno': frame.lineno,
                'vars': frame.locals,
                'context_line': frame.get_source_line(),
                'with_context': frame.get_source_line(context=5),
                'visible': frame.visible,
            }
            frames.append(fdata)
    
        data = {
            'value': transform(collected.exception_value),
            'type': collected.exception_type,
            'message': ''.join(collected.exception_formatted),
            'level': level,
            'frames': frames,
            'traceback': ''.join(traceback.format_exception(*exc_info)),
        }
        modules = [frame['module'] for frame in data['frames']]
        data['versions'] = lookup_versions(modules)
        return capture(event_type, tags=tags, data=data, extra=extra,
                       hash=collected.identification_code)
    finally:
        del exc_info
        if 'collected' in locals():
            del collected
Esempio n. 7
0
def format(type='html', **ops):
    data = collector.collect_exception(*sys.exc_info())
    report = getattr(formatter, 'format_' + type)(data, **ops)
    # report[1] is some head data (if any), like CSS or Javascript
    return report[0]
Esempio n. 8
0
    def respond(self, environ, start_response):
        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()

            # Tell the Registry to save its StackedObjectProxies current state
            # for later restoration
            ## FIXME: needs to be more abstract (something in the environ)
            ## to remove the Paste dependency
            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', 'text/html')]
                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 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 self.xmlhttp_key:
                if self.xmlhttp_key in req.params:
                    exc_data = collector.collect_exception(*exc_info)
                    html, extra_html = formatter.format_html(
                        exc_data, include_hidden_frames=False,
                        include_reusable=False, show_extra_data=False)
                    return [html, extra_html]

            # @@: it would be nice to deal with bad content types here
            return debug_info.content()
Esempio n. 9
0
def handle_exception(exc_info, error_stream, html=True,
                     debug_mode=False,
                     error_email=None,
                     error_log=None,
                     show_exceptions_in_wsgi_errors=False,
                     error_email_from='errors@localhost',
                     smtp_server='localhost',
                     smtp_username=None, 
                     smtp_password=None, 
                     smtp_use_tls=False,
                     error_subject_prefix='',
                     error_message=None,
                     simple_html_error=False,
                     reporters=None,
                     show_error_reason=False
                     ):
    """
    For exception handling outside of a web context

    Use like::

        import sys
        import paste
        import paste.error_middleware
        try:
            do stuff
        except:
            paste.error_middleware.exception_handler(
                sys.exc_info(), paste.CONFIG, sys.stderr, html=False)

    If you want to report, but not fully catch the exception, call
    ``raise`` after ``exception_handler``, which (when given no argument)
    will reraise the exception.
    """
    reported = False
    exc_data = collector.collect_exception(*exc_info)
    extra_data = ''
    if error_email:
        rep = reporter.EmailReporter(
            to_addresses=error_email,
            from_address=error_email_from,
            smtp_server=smtp_server,
            smtp_username=smtp_username,
            smtp_password=smtp_password,
            smtp_use_tls=smtp_use_tls,
            subject_prefix=error_subject_prefix)
        rep_err = send_report(rep, exc_data, html=html)
        if rep_err:
            extra_data += rep_err
        else:
            reported = True
    if reporters:
        for rep in reporters:
            rep_err = send_report(rep, exc_data, html=html)
            if rep_err:
                extra_data += rep_err
            else:
                ## FIXME: should this be true?
                reported = True
    if error_log:
        rep = reporter.LogReporter(
            filename=error_log)
        rep_err = send_report(rep, exc_data, html=html)
        if rep_err:
            extra_data += rep_err
        else:
            reported = True
    if show_exceptions_in_wsgi_errors:
        rep = reporter.FileReporter(
            file=error_stream)
        rep_err = send_report(rep, exc_data, html=html)
        if rep_err:
            extra_data += rep_err
        else:
            reported = True
    else:
        error_stream.write('Error - %s: %s\n' % (
            exc_data.exception_type, exc_data.exception_value))
    if html:
        if debug_mode and simple_html_error:
            return_error = formatter.format_html(
                exc_data, include_hidden_frames=False,
                include_reusable=False, show_extra_data=False)
            reported = True
        elif debug_mode and not simple_html_error:
            error_html = formatter.format_html(
                exc_data,
                include_hidden_frames=True,
                include_reusable=False)
            head_html = ''
            return_error = error_template(
                head_html, error_html, extra_data)
            extra_data = ''
            reported = True
        else:
            default_msg = '''
            An error occurred.  See the error logs for more information.
            '''
            if not show_error_reason:
                default_msg += '''(Turn debug on to display exception reports here)'''

            msg = error_message or default_msg

            if show_error_reason:
                extra = "%s - %s" % (exc_data.exception_type, exc_data.exception_value)
                extra = cgi.escape(extra).encode('ascii', 'xmlcharrefreplace')
            else:
                extra = ''

            return_error = error_template('', msg, extra)
    else:
        return_error = None
    if not reported and error_stream:
        err_report = formatter.format_text(exc_data, show_hidden_frames=True)[0]
        err_report += '\n' + '-'*60 + '\n'
        error_stream.write(err_report)
    if extra_data:
        error_stream.write(extra_data)
    return return_error
Esempio n. 10
0
def handle_exception(
    exc_info,
    error_stream,
    html=True,
    debug_mode=False,
    error_email=None,
    error_log=None,
    show_exceptions_in_wsgi_errors=False,
    error_email_from='errors@localhost',
    smtp_server='localhost',
    smtp_username=None,
    smtp_password=None,
    smtp_use_tls=False,
    error_subject_prefix='',
    error_message=None,
    simple_html_error=False,
    reporters=None,
):
    """
    For exception handling outside of a web context

    Use like::

        import sys
        import paste
        import paste.error_middleware
        try:
            do stuff
        except:
            paste.error_middleware.exception_handler(
                sys.exc_info(), paste.CONFIG, sys.stderr, html=False)

    If you want to report, but not fully catch the exception, call
    ``raise`` after ``exception_handler``, which (when given no argument)
    will reraise the exception.
    """
    reported = False
    exc_data = collector.collect_exception(*exc_info)
    extra_data = ''
    if error_email:
        rep = reporter.EmailReporter(to_addresses=error_email,
                                     from_address=error_email_from,
                                     smtp_server=smtp_server,
                                     smtp_username=smtp_username,
                                     smtp_password=smtp_password,
                                     smtp_use_tls=smtp_use_tls,
                                     subject_prefix=error_subject_prefix)
        rep_err = send_report(rep, exc_data, html=html)
        if rep_err:
            extra_data += rep_err
        else:
            reported = True
    if reporters:
        for rep in reporters:
            rep_err = send_report(rep, exc_data, html=html)
            if rep_err:
                extra_data += rep_err
            else:
                ## FIXME: should this be true?
                reported = True
    if error_log:
        rep = reporter.LogReporter(filename=error_log)
        rep_err = send_report(rep, exc_data, html=html)
        if rep_err:
            extra_data += rep_err
        else:
            reported = True
    if show_exceptions_in_wsgi_errors:
        rep = reporter.FileReporter(file=error_stream)
        rep_err = send_report(rep, exc_data, html=html)
        if rep_err:
            extra_data += rep_err
        else:
            reported = True
    else:
        error_stream.write('Error - %s: %s\n' %
                           (exc_data.exception_type, exc_data.exception_value))
    if html:
        if debug_mode and simple_html_error:
            return_error = formatter.format_html(exc_data,
                                                 include_hidden_frames=False,
                                                 include_reusable=False,
                                                 show_extra_data=False)
            reported = True
        elif debug_mode and not simple_html_error:
            error_html = formatter.format_html(exc_data,
                                               include_hidden_frames=True,
                                               include_reusable=False)
            head_html = ''
            return_error = error_template(head_html, error_html, extra_data)
            extra_data = ''
            reported = True
        else:
            msg = error_message or '''
            An error occurred.  See the error logs for more information.
            (Turn debug on to display exception reports here)
            '''
            return_error = error_template('', msg, '')
    else:
        return_error = None
    if not reported and error_stream:
        err_report = formatter.format_text(exc_data,
                                           show_hidden_frames=True)[0]
        err_report += '\n' + '-' * 60 + '\n'
        error_stream.write(err_report)
    if extra_data:
        error_stream.write(extra_data)
    return return_error
Esempio n. 11
0
def format(type='html', **ops):
    data = collector.collect_exception(*sys.exc_info())
    report = getattr(formatter, 'format_' + type)(data, **ops)
    # report[1] is some head data (if any), like CSS or Javascript
    return report[0]
Esempio n. 12
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()