Example #1
0
    def emit(self, record):
        try:
            request = record.request
            subject = '%s (%s IP): %s' % (
                record.levelname,
                (request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS and 'internal' or 'EXTERNAL'),
                record.msg
            )
            filter = get_exception_reporter_filter(request)
            request_repr = filter.get_request_repr(request)
        except:
            subject = '%s: %s' % (
                record.levelname,
                record.getMessage()
            )
            request = None
            request_repr = "Request repr() unavailable."

        if record.exc_info:
            exc_info = record.exc_info
            stack_trace = '\n'.join(traceback.format_exception(*record.exc_info))
        else:
            exc_info = (None, record.getMessage(), None)
            stack_trace = 'No stack trace available'

        message = "%s\n\n%s" % (stack_trace, request_repr)
        reporter = ExceptionReporter(request, is_email=True, *exc_info)
        html_message = self.include_html and reporter.get_traceback_html() or None
        mail.mail_admins(subject, message, fail_silently=True, html_message=html_message)
Example #2
0
    def emit(self, record):
        try:
            request = record.request
            subject = '%s (%s IP): %s' % (
                record.levelname,
                ('internal' if request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS
                 else 'EXTERNAL'),
                record.getMessage()
            )
            filter = get_exception_reporter_filter(request)
            request_repr = '\n{0}'.format(force_text(filter.get_request_repr(request)))
        except Exception:
            subject = '%s: %s' % (
                record.levelname,
                record.getMessage()
            )
            request = None
            request_repr = "unavailable"
        subject = self.format_subject(subject)

        if record.exc_info:
            exc_info = record.exc_info
        else:
            exc_info = (None, record.getMessage(), None)

        message = "%s\n\nRequest repr(): %s" % (self.format(record), request_repr)
        reporter = ExceptionReporter(request, is_email=True, *exc_info)
        html_message = reporter.get_traceback_html() if self.include_html else None
        
        conn = self.connection()
        conn.send_email('*****@*****.**', 
                        subject,
                        html_message,
                        ['*****@*****.**'],
                        format='html')
Example #3
0
    def emit(self, record):
        if not self.active:
            return

        try:
            request = record.request
        except Exception:
            request = None

        title = '%s: %s' % (record.exc_info[1].__class__.__name__, record.exc_info[1])
        title = title.replace('\n', '\\n').replace('\r', '\\r')

        issue_id = self.get_issue_id(title)
        if not issue_id:
            no_exc_record = copy(record)
            no_exc_record.exc_info = None
            no_exc_record.exc_text = None

            if record.exc_info:
                exc_info = record.exc_info
            else:
                exc_info = (None, record.getMessage(), None)

            reporter = ExceptionReporter(request, is_email=True, *exc_info)
            message = "%s\n\n%s" % (self.format(no_exc_record), reporter.get_traceback_text())
            self.create_issue(title, message)
        else:
            self.reopen_issue(issue_id)
Example #4
0
    def get_data(self, request):
        """
        Gets all data, unpaged, as a list of dicts.
        """
        qs = self.get_initial_queryset(request)
        qs = self.filter_queryset(qs)
        qs = self.ordering(qs)
        data = self.prepare_results(qs)
        try:
            qs = self.get_initial_queryset(request)
            qs = self.filter_queryset(qs)
            qs = self.ordering(qs)
            data = self.prepare_results(qs)
        except Exception as e:
            logger.exception(str(e))

            if settings.DEBUG:
                import sys
                from django.views.debug import ExceptionReporter
                reporter = ExceptionReporter(None, *sys.exc_info())
                text = "\n" + reporter.get_traceback_text()
            else:
                text = "\nAn error occured while processing an AJAX request."

            data = {'error': text}
        return data
Example #5
0
def preview_scribble(request):
    "Render scribble content or return error information."
    if not request.user.is_authenticated():
        return HttpResponseForbidden()
    can_edit = request.user.has_perm('scribbler.change_scribble')
    can_create = request.user.has_perm('scribbler.add_scribble')
    if not (can_edit or can_create):
        return HttpResponseForbidden()
    results = {
        'valid': False,
        'html': '',
    }
    form = PreviewForm(request.POST)
    if form.is_valid():
        results['valid'] = True
        template = Template(form.cleaned_data.get('content', ''))
        context = build_scribble_context(form.instance, request)
        results['html'] = template.render(context)
        results['variables'] = get_variables(context)
    else:
        if hasattr(form, 'exc_info'):
            exc_type, exc_value, tb = form.exc_info
            reporter = ExceptionReporter(request, exc_type, exc_value, tb)
            reporter.get_template_exception_info()
            results['error'] = reporter.template_info
        else:
            # Not sure what to do here
            results['error'] = {
                'message': 'Content is not valid',
                'line': '',
            }
    content = json.dumps(results, cls=DjangoJSONEncoder, ensure_ascii=False)
    return HttpResponse(content, content_type='application/json')
Example #6
0
    def emit(self, record):
        try:
            request = record.request
            subject = '%s (%s IP: %s): %s' % (record.levelname, (request.user if request.user else 'No user'),
                                              ('internal' if request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS else
                                               'EXTERNAL'), record.getMessage())
        except Exception:
            subject = '%s: %s' % (record.levelname, record.getMessage())
            request = None
        subject = self.format_subject(subject)

        # Since we add a nicely formatted traceback on our own, create a copy
        # of the log record without the exception data.
        no_exc_record = copy(record)
        no_exc_record.exc_info = None
        no_exc_record.exc_text = None

        if record.exc_info:
            exc_info = record.exc_info
        else:
            exc_info = (None, record.getMessage(), None)

        reporter = ExceptionReporter(request, is_email=True, *exc_info)
        message = "%s\n\n%s" % (self.format(no_exc_record), reporter.get_traceback_text())
        html_message = reporter.get_traceback_html() if self.include_html else None
        self.send_mail(subject, message, fail_silently=True, html_message=html_message)
Example #7
0
  def emit(self, record):
    import traceback
    from django.views.debug import ExceptionReporter

    try:
      request = record.request
      subject = '%s (%s): %s' % (
        record.levelname,
        request.META.get('REMOTE_ADDR'),
        record.msg
        )
      request_repr = repr(request)
    except Exception:
      subject = '%s: %s' % (
        record.levelname,
        record.msg
        )
      request = None
      request_repr = "Request repr() unavailable"

    if record.exc_info:
      exc_info = record.exc_info
      stack_trace = '\n'.join(traceback.format_exception(*record.exc_info))
    else:
      exc_info = (None, record.msg, None)
      stack_trace = 'No stack trace available'

    message = "%s\n\n%s" % (stack_trace, request_repr)
    reporter = ExceptionReporter(request, is_email=True, *exc_info)
    html_message = self.include_html and reporter.get_traceback_html() or None
    #        mail_admins(subject, message, fail_silently=True,
    mail_admins(subject, message, html_message=html_message)
Example #8
0
    def test_exception_fetching_user(self):
        """
        The error page can be rendered if the current user can't be retrieved
        (such as when the database is unavailable).
        """
        class ExceptionUser:
            def __str__(self):
                raise Exception()

        request = self.rf.get('/test_view/')
        request.user = ExceptionUser()

        try:
            raise ValueError('Oops')
        except ValueError:
            exc_type, exc_value, tb = sys.exc_info()

        reporter = ExceptionReporter(request, exc_type, exc_value, tb)
        html = reporter.get_traceback_html()
        self.assertInHTML('<h1>ValueError at /test_view/</h1>', html)
        self.assertIn('<pre class="exception_value">Oops</pre>', html)
        self.assertIn('<h3 id="user-info">USER</h3>', html)
        self.assertIn('<p>[unable to retrieve the current user]</p>', html)

        text = reporter.get_traceback_text()
        self.assertIn('USER: [unable to retrieve the current user]', text)
Example #9
0
    def emit(self, record):
        try:
            request = record.request
            subject = '%s (%s IP): %s' % (
                record.levelname,
                ('internal' if request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS
                 else 'EXTERNAL'),
                record.getMessage()
            )
            filter = get_exception_reporter_filter(request)
            request_repr = '\n{}'.format(force_text(filter.get_request_repr(request)))
        except Exception:
            subject = '%s: %s' % (
                record.levelname,
                record.getMessage()
            )
            request = None
            request_repr = "unavailable"
        subject = self.format_subject(subject)

        if record.exc_info:
            exc_info = record.exc_info
        else:
            exc_info = (None, record.getMessage(), None)

        message = "%s\n\nRequest repr(): %s" % (self.format(record), request_repr)
        reporter = ExceptionReporter(request, is_email=True, *exc_info)
        html_message = reporter.get_traceback_html() if self.include_html else None
        self.send_mail(subject, message, fail_silently=True, html_message=html_message)
Example #10
0
def render_to_json(response, *args, **kwargs):
    """
    Creates the main structure and returns the JSON response.
    """
    # determine the status code
    if hasattr(response, 'status_code'):
        status_code = response.status_code
    elif issubclass(type(response), Http404):
        status_code = 404
    elif issubclass(type(response), Exception):
        status_code = 500
        logger.exception(str(response), extra={'request': kwargs.pop('request', None)})
        
        if settings.DEBUG:
            import sys
            reporter = ExceptionReporter(None, *sys.exc_info())
            text = reporter.get_traceback_text()
            response = HttpResponseServerError(text, content_type='text/plain')
        else:
            response = HttpResponseServerError("An error occured while processing an AJAX request.", content_type='text/plain')
    else:
        status_code = 200

    # creating main structure
    data = {
        'status': status_code,
        'statusText': REASON_PHRASES.get(status_code, 'UNKNOWN STATUS CODE'),
        'content': response
    }

    return JSONResponse(data,  *args, **kwargs)
Example #11
0
 def log_exception_data(self, exception, exc_type, exc_value, tb, queue_name='default'):
     key = self._make_key(exc_type, str(exception))
     exc_log_entry = None
     
     if key not in self._exceptions:
         from django.views.debug import ExceptionReporter
         
         # first arg to ExceptionReporter.__init__() is usually a request object
         reporter = ExceptionReporter(None, exc_type, exc_value, tb)
         html = reporter.get_traceback_html()
         
         exc_log_entry = self.create(
             exception_type=exc_type.__name__,
             exception_module=getattr(exc_type, '__module__', "None"),
             queue_name=queue_name,
             message=str(exception),
             html=html,
         )
         self._exceptions.update({ key: exc_log_entry, })
     
     else:
         exc_log_entry = self._exceptions[key]
         exc_log_entry.increment()
         exc_log_entry.save()
     
     return exc_log_entry
Example #12
0
def better_uncaught_exception_emails(self, request, resolver, exc_info):
    """
    Processing for any otherwise uncaught exceptions (those that will
    generate HTTP 500 responses). Can be overridden by subclasses who want
    customised 500 handling.

    Be *very* careful when overriding this because the error could be
    caused by anything, so assuming something like the database is always
    available would be an error.
    """
    from django.conf        import settings
    from django.core.mail   import EmailMultiAlternatives
    from django.views.debug import ExceptionReporter

    # Only send details emails in the production environment.
    if settings.DEBUG == False:
        reporter = ExceptionReporter(request, *exc_info)

        # Prepare the email headers for sending.
        from_    = u"Exception Reporter <*****@*****.**>"
        to_      = from_

        subject  = "Detailed stack trace."

        message = EmailMultiAlternatives(subject, reporter.get_traceback_text(), from_, [to_])
        message.attach_alternative(reporter.get_traceback_html(), 'text/html')
        message.send()

    # Make sure to then just call the base handler.
    return self.original_handle_uncaught_exception(request, resolver, exc_info)
Example #13
0
    def handle_exception(self, exc, request):
        from django.utils.log import getLogger
        from django.conf import settings

        logger = getLogger('django.request')
        exc_info = sys.exc_info()

        logger.error(
            'Internal Server Error: %s', request.path,
            exc_info=exc_info,
            extra={
                'status_code': 500,
                'request': request
            }
        )

        resp = HttpResponse('', status=500, content_type='text/plain')
        resp.content = ''

        if hasattr(exc, 'resp_obj'):
            resp = exc.resp_obj
            resp.status_code = 500
            resp.set_common_headers(request)
        else:
            resp = HttpResponse('', status=500, content_type='text/plain')

        resp.content = 'An error occured.'

        if settings.DEBUG:
            from django.views.debug import ExceptionReporter
            reporter = ExceptionReporter(request, *exc_info)
            resp.content = reporter.get_traceback_text()

        resp['Content-Type'] = 'text/plain'
        return resp
Example #14
0
    def emit(self, record):
        try:
            request = record.request
            subject = "%s (%s IP): %s" % (
                record.levelname,
                ("internal" if request.META.get("REMOTE_ADDR") in settings.INTERNAL_IPS else "EXTERNAL"),
                record.getMessage(),
            )
            filter = get_exception_reporter_filter(request)
            request_repr = filter.get_request_repr(request)
        except Exception:
            subject = "%s: %s" % (record.levelname, record.getMessage())
            request = None
            request_repr = "Request repr() unavailable."
        subject = self.format_subject(subject)

        if record.exc_info:
            exc_info = record.exc_info
            stack_trace = "\n".join(traceback.format_exception(*record.exc_info))
        else:
            exc_info = (None, record.getMessage(), None)
            stack_trace = "No stack trace available"

        message = "%s\n\n%s" % (stack_trace, request_repr)
        reporter = ExceptionReporter(request, is_email=True, *exc_info)
        html_message = reporter.get_traceback_html() if self.include_html else None
        mail.mail_admins(subject, message, fail_silently=True, html_message=html_message, connection=self.connection())
Example #15
0
    def test_ignore_traceback_evaluation_exceptions(self):
        """
        Don't trip over exceptions generated by crafted objects when
        evaluating them while cleansing (#24455).
        """

        class BrokenEvaluation(Exception):
            pass

        def broken_setup():
            raise BrokenEvaluation

        request = self.rf.get("/test_view/")
        broken_lazy = SimpleLazyObject(broken_setup)
        try:
            bool(broken_lazy)
        except BrokenEvaluation:
            exc_type, exc_value, tb = sys.exc_info()

        reporter = ExceptionReporter(request, exc_type, exc_value, tb)
        try:
            html = reporter.get_traceback_html()
        except BrokenEvaluation:
            self.fail("Broken evaluation in traceback is not caught.")

        self.assertIn("BrokenEvaluation", html, "Evaluation exception reason not mentioned in traceback")
Example #16
0
def progress_error_reporter():
    """
    Use this wrapper around your progress loops like this:

    >>> with progress_error_reporter():
    >>>     for item in with_progress(collection, name='my long process that can throw errors')
    >>>         # heavy processing actions with sometimes an exception :-)

    When an exception gets raised from inside the body of your for-loop, it will be
    caught and the progress bar will show a link to the exception. The exception is rendered
    by the standard exception reporter, containing the full stack trace with variables.
    """
    try:
        yield
    except Exception as exc_outer:
        try:
            if hasattr(tls, 'djprogress__stack') and tls.djprogress__stack:
                from djprogress.models import Progress

                progress_id = tls.djprogress__stack.pop()
                progress = Progress.objects.get(pk=progress_id)
                exc_type, exc_value, exc_traceback = sys.exc_info()
                er = ExceptionReporter(None, exc_type, exc_value, exc_traceback)
                html = er.get_traceback_html()
                progress.exception = html
                progress.save()
        except Exception as exc_inner:
            # When the error reporter fails for whatever reason, catch and log the
            # exception here so that our regular code flow isn't interrupted. The
            # 'raise' statement will take care of the rest.
            logger.exception(exc_inner)
        raise exc_outer
Example #17
0
    def format(self, record):
        """Format exception object as a string"""
        data = record._raw.copy()

        data['extra'] = self.prepare_data(data.get('extra'))


        if 'exc_info' in data and data['exc_info']:
            if DJANGO_ENABLE:
                er = ExceptionReporter(None, *data['exc_info'])
                data['exc_extra_info'] = self.prepare_data(er.get_traceback_frames())
            data['exc_info'] = self.formatException(data['exc_info'])

        data['msg'] = logging.Formatter.format(self, record)
        data['format'] = data['msg']
        del data['args']

        # hack for normalize unicode data for soap fault
        for key in ['exc_info', 'format']:
            if isinstance(data[key], basestring):
                try:
                    data[key] = data[key].decode("unicode_escape")
                except UnicodeEncodeError:
                    pass
        return data
    def emit(self, record):

        try:
            request = record.request
        except Exception:
            request = None

        subject = '%s: %s' % (
            record.levelname,
            record.getMessage()
        )
        subject = subject.replace('\n', '\\n').replace('\r', '\\r')

        # Since we add a nicely formatted traceback on our own, create a copy
        # of the log record without the exception data.
        no_exc_record = copy(record)
        no_exc_record.exc_info = None
        no_exc_record.exc_text = None

        if record.exc_info:
            exc_info = record.exc_info
        else:
            exc_info = (None, record.getMessage(), None)
        if settings.HACKATHON_DEV_EMAILS:
            reporter = ExceptionReporter(request, is_email=True, *exc_info)
            message = "%s\n\n%s" % (self.format(no_exc_record), reporter.get_traceback_text())
            html_message = reporter.get_traceback_html()
            msg = EmailMultiAlternatives(subject,
                                         message,
                                         'server@' + settings.HACKATHON_DOMAIN,
                                         settings.HACKATHON_DEV_EMAILS)
            msg.attach_alternative(html_message, 'text/html')
            msg.send(fail_silently=True)
Example #19
0
    def emit(self, record):

        try:
            request = record.request
            subject = "%s (%s IP): %s" % (
                record.levelname,
                ("internal" if request.META.get("REMOTE_ADDR") in settings.INTERNAL_IPS else "EXTERNAL"),
                record.getMessage(),
            )
        except Exception:
            subject = "%s: %s" % (record.levelname, record.getMessage())
            request = None

        if record.exc_info:
            exc_info = record.exc_info
        else:
            exc_info = (None, record.getMessage(), None)

        reporter = ExceptionReporter(request, is_email=False, *exc_info)
        html_message = reporter.get_traceback_html()

        print "BAD HOST", record
        DisallowedHost.objects.create(
            http_host=request.META.get("HTTP_HOST") if request else None,
            remote_addr=request.META.get("REMOTE_ADDR") if request else None,
            http_x_forwarded_for=request.META.get("HTTP_X_FORWARDED_FOR") if request else None,
            request_uri=request.META.get("REQUEST_URI") if request else None,
            request_method=request.META.get("REQUEST_METHOD") if request else None,
            query_string=request.META.get("QUERY_STRING") if request else None,
            path_info=request.META.get("PATH_INFO") if request else None,
            http_user_agent=request.META.get("HTTP_USER_AGENT") if request else None,
            html_report=html_message,
        )
Example #20
0
    def test_reporting_of_nested_exceptions(self):
        request = self.rf.get('/test_view/')
        try:
            try:
                raise AttributeError(mark_safe('<p>Top level</p>'))
            except AttributeError as explicit:
                try:
                    raise ValueError(mark_safe('<p>Second exception</p>')) from explicit
                except ValueError:
                    raise IndexError(mark_safe('<p>Final exception</p>'))
        except Exception:
            # Custom exception handler, just pass it into ExceptionReporter
            exc_type, exc_value, tb = sys.exc_info()

        explicit_exc = 'The above exception ({0}) was the direct cause of the following exception:'
        implicit_exc = 'During handling of the above exception ({0}), another exception occurred:'

        reporter = ExceptionReporter(request, exc_type, exc_value, tb)
        html = reporter.get_traceback_html()
        # Both messages are twice on page -- one rendered as html,
        # one as plain text (for pastebin)
        self.assertEqual(2, html.count(explicit_exc.format('&lt;p&gt;Top level&lt;/p&gt;')))
        self.assertEqual(2, html.count(implicit_exc.format('&lt;p&gt;Second exception&lt;/p&gt;')))
        self.assertEqual(10, html.count('&lt;p&gt;Final exception&lt;/p&gt;'))

        text = reporter.get_traceback_text()
        self.assertIn(explicit_exc.format('<p>Top level</p>'), text)
        self.assertIn(implicit_exc.format('<p>Second exception</p>'), text)
        self.assertEqual(3, text.count('<p>Final exception</p>'))
Example #21
0
    def get_response(self, request):
        exc_type, exc_value, traceback = sys.exc_info()
        reporter = ExceptionReporter(
            request,
            exc_type,
            exc_value,
            traceback.tb_next
        )
        html = reporter.get_traceback_html()
        http_response = http.HttpResponseServerError()

        if settings.DEBUG:
            http_response = http.HttpResponseServerError(
                html,
                content_type='text/html; charset=utf-8'
            )
        elif getattr(settings, 'EMAIL_CRASHES', False):
            # Send Email Crash Report
            subject = 'django-firestone crash report'
            message = EmailMessage(
                subject=settings.EMAIL_SUBJECT_PREFIX + subject,
                body=html,
                from_email=settings.SERVER_EMAIL,
                to=[admin[1] for admin in settings.ADMINS]
            )
            message.content_subtype = 'html'
            message.send(fail_silently=True)

        return http_response
Example #22
0
File: ajax.py Project: HiPiH/life
 def __call__(self, req):
     if req.method!="POST": 
         return JsonResponse(ajax_error(405, 'Accepts only POST request'))
     
     try:
         ajax_method=req.POST['ajax_method']
         if not hasattr(self, ajax_method):
             return JsonResponse(ajax_error(405,"Unknown ajax method '%s'" % ajax_method))
         method = getattr(self, ajax_method)
         
         post=dict(req.POST)
         del post['ajax_method']
         kwargs = {}
         for name in post:
             value = post[name]
             if len(value)==1:
                 value=value[0]
             kwargs[str(name)] = value
         return JsonResponse(method(req, **kwargs))
         
     except Exception, e:
         try:
             if dblogger:                
                 exc_info = sys.exc_info()
                 report = ExceptionReporter(req, *exc_info)
                 dblogger.exception(e, report.get_traceback_html())
         except:
             pass            
         return JsonResponse(ajax_error(405,"Server Exception: %s:%s" % (e.__class__, e)))
    def get_context_data(self, *args, **kwargs):
        try:
            self.initialize(*args, **kwargs)

            qs = self.get_initial_queryset()

            # number of records before filtering
            total_records = qs.count()

            qs = self.filter_queryset(qs)

            # number of records after filtering
            total_display_records = qs.count()

            qs = self.ordering(qs)
            qs = self.paging(qs)

            # prepare output data
            if self.pre_camel_case_notation:
                aaData = self.prepare_results(qs)

                ret = {'sEcho': int(self._querydict.get('sEcho', 0)),
                       'iTotalRecords': total_records,
                       'iTotalDisplayRecords': total_display_records,
                       'aaData': aaData
                       }
            else:
                data = self.prepare_results(qs)

                ret = {'draw': int(self._querydict.get('draw', 0)),
                       'recordsTotal': total_records,
                       'recordsFiltered': total_display_records,
                       'data': data
                }
        except Exception as e:
            logger.exception(str(e))

            if settings.DEBUG:
                import sys
                from django.views.debug import ExceptionReporter
                reporter = ExceptionReporter(None, *sys.exc_info())
                text = "\n" + reporter.get_traceback_text()
            else:
                text = "\nAn error occured while processing an AJAX request."

            if self.pre_camel_case_notation:
                ret = {'result': 'error',
                       'sError': text,
                       'text': text,
                       'aaData': [],
                       'sEcho': int(self._querydict.get('sEcho', 0)),
                       'iTotalRecords': 0,
                       'iTotalDisplayRecords': 0, }
            else:
                ret = {'error': text,
                       'data': [],
                       'recordsTotal': 0,
                       'recordsFiltered': 0,
                       'draw': int(self._querydict.get('draw', 0))}
        return ret
Example #24
0
    def error_handler(self, e, request, meth, em_format):
        """
        Override this method to add handling of errors customized for your
        needs
        """
        if isinstance(e, FormValidationError):
            return self.form_validation_response(e, self.determine_emitter(request))

        elif isinstance(e, TypeError):
            result = rc.BAD_REQUEST

            msg = "Method signature does not match.\n\n"

            try:
                hm = HandlerMethod(meth)
                sig = hm.signature

            except TypeError:
                msg += "Signature could not be determined"

            else:
                if sig:
                    msg += "Signature should be: %s" % sig
                else:
                    msg += "Resource does not expect any parameters."

            if self.display_errors:
                msg += "\n\nException was: %s" % str(e)

            result.content = format_error(msg)
            return result
        elif isinstance(e, Http404):
            return rc.NOT_FOUND

        elif isinstance(e, HttpStatusCode):
            return e.response

        else:
            """
            On errors (like code errors), we'd like to be able to
            give crash reports to both admins and also the calling
            user. There's two setting parameters for this:

            Parameters::
             - `PISTON_EMAIL_ERRORS`: Will send a Django formatted
               error email to people in `settings.ADMINS`.
             - `PISTON_DISPLAY_ERRORS`: Will return a simple traceback
               to the caller, so he can tell you what error they got.

            If `PISTON_DISPLAY_ERRORS` is not enabled, the caller will
            receive a basic "500 Internal Server Error" message.
            """
            exc_type, exc_value, tb = sys.exc_info()
            rep = ExceptionReporter(request, exc_type, exc_value, tb.tb_next)
            if self.email_errors:
                self.email_exception(rep)
            if self.display_errors:
                return HttpResponseServerError(format_error("\n".join(rep.format_exception())))
            else:
                raise
Example #25
0
    def create_from_exception(self, exception=None, traceback=None, **kwargs):
        """
        Creates an error log from an exception.
        """
        if not exception:
            exc_type, exc_value, traceback = sys.exc_info()
        elif not traceback:
            warnings.warn('Using just the ``exception`` argument is deprecated, send ``traceback`` in addition.', DeprecationWarning)
            exc_type, exc_value, traceback = sys.exc_info()
        else:
            exc_type = exception.__class__
            exc_value = exception

        def to_unicode(f):
            if isinstance(f, dict):
                nf = dict()
                for k, v in f.iteritems():
                    nf[str(k)] = to_unicode(v)
                f = nf
            elif isinstance(f, (list, tuple)):
                f = [to_unicode(f) for f in f]
            else:
                try:
                    f = smart_unicode(f)
                except (UnicodeEncodeError, UnicodeDecodeError):
                    f = '(Error decoding value)'
            return f

        def shorten(var):
            if not isinstance(var, basestring):
                var = to_unicode(var)
            if len(var) > 500:
                var = var[:500] + '...'
            return var

        reporter = ExceptionReporter(None, exc_type, exc_value, traceback)
        frames = varmap(shorten, reporter.get_traceback_frames())

        data = kwargs.pop('data', {}) or {}
        data['__sentry__'] = {
            'exc': map(to_unicode, [exc_type.__class__.__module__, exc_value.args, frames]),
        }

        if isinstance(exc_value, TemplateSyntaxError) and hasattr(exc_value, 'source'):
            origin, (start, end) = exc_value.source
            data['__sentry__'].update({
                'template': (origin.reload(), start, end, origin.name),
            })
        
        tb_message = '\n'.join(traceback_mod.format_exception(exc_type, exc_value, traceback))

        kwargs.setdefault('message', to_unicode(exc_value))

        return self._create(
            class_name=exc_type.__name__,
            traceback=tb_message,
            data=data,
            **kwargs
        )
Example #26
0
    def emit(self, record):
        """Send a log error over email.
 
        Args:
            The logging.LogRecord object.
                See http://docs.python.org/library/logging.html#logging.LogRecord
        """
        from django.conf import settings

        if settings.DEBUG and record.levelno < logging.WARNING:
            # NOTE: You don't want to try this on dev_appserver. Trust me.
            return
 
        signature = self.__GetRecordSignature(record)

        try:
            from google.appengine.api import memcache
            if not memcache.add(signature, True, time=self.log_interval):
                return
        except Exception:
            pass
 
        formatted_record = self.format(record)

        request = None
        try:
            if sys.version_info < (2, 5):
                # A nasty workaround required because Python 2.4's logging
                # module doesn't support passing in extra context.
                # For this handler, the only extra data we need is the
                # request, and that's in the top stack frame.
                request = record.exc_info[2].tb_frame.f_locals['request']
            else:
                request = record.request
        except Exception:
            pass
            
        try:
            for jid, params in self.recipients.items():
                if record.levelno < params['level']:
                    continue
 
                sender = 'errors@%s.appspotmail.com' % app_id
                subject = '(%s) error reported for %s, version %s' % (record.levelname, app_id, app_ver)
                message = formatted_record

                exc_info = record.exc_info if record.exc_info else (None, record.msg, None)
                reporter = ExceptionReporter(request, is_email=True, *exc_info)
                html_message = reporter.get_traceback_html() or None

                mail = EmailMultiAlternatives('%s%s' % (settings.EMAIL_SUBJECT_PREFIX, subject),
                                              message, sender, [jid])
                if html_message:
                    mail.attach_alternative(html_message, 'text/html')
                mail.send()
        except OverQuotaError:
            pass
        except Exception:
            self.handleError(record)
Example #27
0
    def emit(self, record):
        try:
            request = record.request
            subject = '%s (%s IP): %s' % (
                record.levelname,
                ('internal' if request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS
                    else 'EXTERNAL'),
                record.getMessage(),
            )
        except Exception:
            subject = '%s: %s' % (
                record.levelname,
                record.getMessage(),
            )
            request = None
        subject = self.format_subject(subject)

        # Since we add a nicely formatted traceback on our own, create a copy
        # of the log record without the exception data.
        no_exc_record = copy.copy(record)
        no_exc_record.exc_info = None
        no_exc_record.exc_text = None

        if record.exc_info:
            exc_info = record.exc_info
        else:
            exc_info = (None, record.getMessage(), None)

        reporter = ExceptionReporter(request, is_email=True, *exc_info)

        try:
            tb = reporter.get_traceback_text()
        except:
            tb = "(An exception occured when getting the traceback text)"

            if reporter.exc_type:
                tb = "%s (An exception occured when rendering the traceback)" \
                    % reporter.exc_type.__name__

        message = "%s\n\n%s" % (self.format(no_exc_record), tb)

        colors = {
            'ERROR': 'danger',
            'WARNING': 'warning',
            'INFO': 'good',
        }

        attachments = {
            'title': subject,
            'text': message,
            'color': colors.get(record.levelname, '#AAAAAA'),
        }

        attachments.update(self.kwargs)
        self.send_message(
            self.template,
            {'text': subject},
            self.generate_attachments(**attachments),
        )
Example #28
0
    def create_from_exception(self, exception=None, traceback=None, **kwargs):
        """
        Creates an error log from an exception.
        """
        if not exception:
            exc_type, exc_value, traceback = sys.exc_info()
        elif not traceback:
            warnings.warn(
                "Using just the ``exception`` argument is deprecated, send ``traceback`` in addition.",
                DeprecationWarning,
            )
            exc_type, exc_value, traceback = sys.exc_info()
        else:
            exc_type = exception.__class__
            exc_value = exception

        def to_unicode(f):
            if isinstance(f, dict):
                nf = dict()
                for k, v in f.iteritems():
                    nf[str(k)] = to_unicode(v)
                f = nf
            elif isinstance(f, (list, tuple)):
                f = [to_unicode(f) for f in f]
            else:
                try:
                    f = smart_unicode(f)
                except (UnicodeEncodeError, UnicodeDecodeError):
                    f = "(Error decoding value)"
                except Exception:  # in some cases we get a different exception
                    f = smart_unicode(type(f))
            return f

        def shorten(var):
            if not isinstance(var, basestring):
                var = to_unicode(var)
            if len(var) > 500:
                var = var[:500] + "..."
            return var

        reporter = ExceptionReporter(None, exc_type, exc_value, traceback)
        frames = varmap(shorten, reporter.get_traceback_frames())

        data = kwargs.pop("data", {}) or {}
        data["__sentry__"] = {"exc": map(to_unicode, [exc_type.__class__.__module__, exc_value.args, frames])}

        if isinstance(exc_value, TemplateSyntaxError) and hasattr(exc_value, "source"):
            origin, (start, end) = exc_value.source
            data["__sentry__"].update({"template": (origin.reload(), start, end, origin.name)})

        tb_message = "\n".join(traceback_mod.format_exception(exc_type, exc_value, traceback))

        kwargs.setdefault("message", to_unicode(exc_value))

        return self.process(class_name=exc_type.__name__, traceback=tb_message, data=data, **kwargs)
Example #29
0
 def test_auditing(self):
     def foo():
         return bar()
     def bar():
         return baz()
     def baz():
         return auditing.FakeTraceback()
     tb = foo()
     er = ExceptionReporter(None, type, None, tb)
     # if this fails we've messed up the fake traceback
     html = er.get_traceback_html()
Example #30
0
 def test_message_only(self):
     reporter = ExceptionReporter(None, None, "I'm a little teapot", None)
     html = reporter.get_traceback_html()
     self.assertIn('<h1>Report</h1>', html)
     self.assertIn('<pre class="exception_value">I&#39;m a little teapot</pre>', html)
     self.assertNotIn('<th>Request Method:</th>', html)
     self.assertNotIn('<th>Request URL:</th>', html)
     self.assertNotIn('<th>Exception Type:</th>', html)
     self.assertNotIn('<th>Exception Value:</th>', html)
     self.assertNotIn('<h2>Traceback ', html)
     self.assertIn('<h2>Request information</h2>', html)
     self.assertIn('<p>Request data not supplied</p>', html)
Example #31
0
    def get_context_data(self, *args, **kwargs):
        try:
            self.initialize(*args, **kwargs)

            qs = self.get_initial_queryset()

            # number of records before filtering
            total_records = qs.count()

            qs = self.filter_queryset(qs)

            # number of records after filtering
            total_display_records = qs.count()

            qs = self.ordering(qs)
            # 导出多少条日志
            download_numbers = self.request.DATA.get("download_numbers", 0)
            if download_numbers != 0:
                qs = qs[:int(download_numbers)]
            else:
                qs = self.paging(qs)
            if self.enable_es:
                self.es_result = self.search_from_es(qs)

            # prepare output data
            if self.pre_camel_case_notation:
                aaData = self.prepare_results(qs)

                ret = {
                    'sEcho': int(self._querydict.get('sEcho', 0)),
                    'iTotalRecords': total_records,
                    'iTotalDisplayRecords': total_display_records,
                    'aaData': aaData
                }
            else:
                data = self.prepare_results(qs)

                ret = {
                    'draw': int(self._querydict.get('draw', 0)),
                    'recordsTotal': total_records,
                    'recordsFiltered': total_display_records,
                    'data': data
                }
        except Exception as e:
            logger.error(e.message, exc_info=True)

            if settings.DEBUG:
                reporter = ExceptionReporter(None, *sys.exc_info())
                text = "\n" + reporter.get_traceback_text()
            else:
                reporter = ExceptionReporter(None, *sys.exc_info())
                err_text = "\n" + reporter.get_traceback_text()
                notify_administrator(content=err_text, title='Datatable错误')
                text = "\nAn error occured while processing an AJAX request."
            if self.pre_camel_case_notation:
                ret = {
                    'result': 'error',
                    'sError': text,
                    'text': text,
                    'aaData': [],
                    'sEcho': int(self._querydict.get('sEcho', 0)),
                    'iTotalRecords': 0,
                    'iTotalDisplayRecords': 0,
                }
            else:
                ret = {
                    'error': text,
                    'data': [],
                    'recordsTotal': 0,
                    'recordsFiltered': 0,
                    'draw': int(self._querydict.get('draw', 0))
                }

        if self.request.DATA.get("dts_download", 0) == 1:

            datatable = ret.get("data", []) or ret.get("aaData", [])
            filename = getattr(self.request, "filename", "数据表")
            filename = filename + "_%s.xls"
            filename = filename % int(time.time())
            if self.custom_template:
                labels, headers = self.handle_custom_template()
            else:
                labels = getattr(self.request, "labels", ())
                headers = getattr(self.request, "headers", ())
            file_path = excel_export(filename, labels, headers, datatable)
            file_path = "http://%s/%s" % (self.request.META.get('HTTP_HOST'),
                                          file_path)
            # ret = dict()
            ret["status"] = 200
            ret["msg"] = "下载成功"
            ret["file_path"] = file_path
            min_len = min(len(datatable), 10)
            if min_len:
                ret["data"] = []
        return ret
Example #32
0
    def error_handler(self, response, e, request, meth):
        """
        Override this method to add handling of errors customized for your
        needs
        """
        response.status_code = 500
        if isinstance(e,
                      (PistonException, PistonBadRequestException,
                       PistonForbiddenException, PistonMethodException,
                       PistonNotFoundException, PistonUnauthorizedException)):
            response.status_code = e.status_code
            response.error_message = e.message
            response.headers.update(e.headers)
        elif isinstance(e, FormValidationError):
            response.status_code = 400
            response.form_errors = e.form.errors
        elif isinstance(e, TypeError) and meth:
            hm = HandlerMethod(meth)
            sig = hm.signature

            msg = 'Method signature does not match.\n\n'

            if sig:
                msg += 'Signature should be: %s' % sig
            else:
                msg += 'Resource does not expect any parameters.'

            if self.display_errors:
                msg += '\n\nException was: %s' % str(e)

            response.error_message = format_error(msg)
        # TODO: As we start using Piston exceptions, the following 2 errors can be phased out
        elif isinstance(e, Http404):
            response.status_code = 404
            response.error_message = 'Not Found'
        elif isinstance(e, HttpStatusCode):
            response.error_message = e.response
        else:
            """
            On errors (like code errors), we'd like to be able to
            give crash reports to both admins and also the calling
            user. There's two setting parameters for this:

            Parameters::
             - `PISTON_EMAIL_ERRORS`: Will send a Django formatted
               error email to people in `settings.ADMINS`.
             - `PISTON_DISPLAY_ERRORS`: Will return a simple message/full traceback
               depending on `PISTON_DISPLAY_TRACEBACK`. Default is simple message
               to the caller, so he can tell you what error they got.

            If `PISTON_DISPLAY_ERRORS` is not enabled, the caller will
            receive a basic "500 Internal Server Error" message.
            """
            exc_type, exc_value, tb = sys.exc_info()
            rep = ExceptionReporter(request, exc_type, exc_value, tb.tb_next)
            if self.email_errors:
                self.email_exception(rep)
            if self.display_errors:
                if self.display_traceback:
                    response.error_message = format_error('\n'.join(
                        rep.format_exception()))
                else:
                    response.error_message = str(e)
            else:
                raise
Example #33
0
    def get_context_data(self, *args, **kwargs):
        try:
            self.es_query_dict = dict()
            self.doc_type = ""
            # 新旧版本区分 √
            self.initialize(*args, **kwargs)
            # 不知道要做什么先
            qs = self.get_initial_queryset()

            # 添加过滤条件 √
            self.filter_queryset()

            # 排序字典 √
            self.ordering()
            # 分页 √
            self.paging()

            # 加index
            self.es_query_dict["index"] = self.index

            # 从es获取数据
            result = get_by_any(**self.es_query_dict)

            # 获取查询结果集
            all_hits = result['hits']['hits']

            qs = [ah['_source'] for ah in all_hits]

            # 总条数
            total_records = result['hits']['total']
            # 总显示条数
            total_display_records = total_records

            # 处理数据 √
            output_data = self.prepare_results(qs)

            if self.pre_camel_case_notation:

                ret = {
                    'sEcho': int(self.querydict.get('sEcho', 0)),
                    'iTotalRecords': total_records,
                    'iTotalDisplayRecords': total_display_records,
                    'aaData': output_data
                }
            else:

                ret = {
                    'draw': int(self.querydict.get('draw', 0)),
                    'recordsTotal': total_records,
                    'recordsFiltered': total_display_records,
                    'data': output_data
                }
        except (Exception, elasticsearch.TransportError,
                elasticsearch.NotFoundError) as e:
            logger.exception(str(e))

            if settings.DEBUG:
                reporter = ExceptionReporter(None, *sys.exc_info())
                text = "\n" + reporter.get_traceback_text()
            else:
                reporter = ExceptionReporter(None, *sys.exc_info())
                err_text = "\n" + reporter.get_traceback_text()
                notify_administrator(content=err_text, title='Datatable错误')
                text = "\nAn error occured while processing an AJAX request."

            if self.pre_camel_case_notation:
                ret = {
                    'result': 'error',
                    'sError': text,
                    'text': text,
                    'aaData': [],
                    'sEcho': int(self.querydict.get('sEcho', 0)),
                    'iTotalRecords': 0,
                    'iTotalDisplayRecords': 0,
                }
            else:
                ret = {
                    'data': [],
                    'recordsTotal': 0,
                    'recordsFiltered': 0,
                    'draw': int(self.querydict.get('draw', 0))
                }
                if settings.DEBUG:
                    ret["error"] = text

        return ret
Example #34
0
            """
            On errors (like code errors), we'd like to be able to
            give crash reports to both admins and also the calling
            user. There's two setting parameters for this:
            
            Parameters::
             - `PISTON_EMAIL_ERRORS`: Will send a Django formatted
               error email to people in `settings.ADMINS`.
             - `PISTON_DISPLAY_ERRORS`: Will return a simple traceback
               to the caller, so he can tell you what error they got.
               
            If `PISTON_DISPLAY_ERRORS` is not enabled, the caller will
            receive a basic "500 Internal Server Error" message.
            """
            exc_type, exc_value, tb = sys.exc_info()
            rep = ExceptionReporter(request, exc_type, exc_value, tb.tb_next)
            if self.email_errors:
                self.email_exception(rep)
            if self.display_errors:
                return HttpResponseServerError(
                    format_error('\n'.join(rep.format_exception())))
            else:
                raise

        emitter, ct = Emitter.get(em_format)
        srl = emitter(result, typemapper, handler, handler.fields, anonymous)

        try:
            """
            Decide whether or not we want a generator here,
            or we just want to buffer up the entire result
Example #35
0
    def get_context_data(self, *args, **kwargs):
        request = self.request
        try:
            self.initialize(*args, **kwargs)

            qs = self.get_initial_queryset()

            # number of records before filtering
            total_records = qs.count()

            qs = self.filter_queryset(qs)

            # number of records after filtering
            total_display_records = qs.count()

            qs = self.ordering(qs)
            qs = self.paging(qs)

            # prepare output data
            if self.pre_camel_case_notation:
                aaData = self.prepare_results(qs)

                ret = {
                    'sEcho': int(request.REQUEST.get('sEcho', 0)),
                    'iTotalRecords': total_records,
                    'iTotalDisplayRecords': total_display_records,
                    'aaData': aaData
                }
            else:
                data = self.prepare_results(qs)

                ret = {
                    'draw': int(request.REQUEST.get('draw', 0)),
                    'recordsTotal': total_records,
                    'recordsFiltered': total_display_records,
                    'data': data
                }
        except Exception as e:
            logger.exception(str(e))

            if settings.DEBUG:
                import sys
                from django.views.debug import ExceptionReporter
                reporter = ExceptionReporter(None, *sys.exc_info())
                text = "\n" + reporter.get_traceback_text()
            else:
                text = "\nAn error occured while processing an AJAX request."

            if self.pre_camel_case_notation:
                ret = {
                    'result': 'error',
                    'sError': text,
                    'text': text,
                    'aaData': [],
                    'sEcho': int(request.REQUEST.get('sEcho', 0)),
                    'iTotalRecords': 0,
                    'iTotalDisplayRecords': 0,
                }
            else:
                ret = {
                    'error': text,
                    'data': [],
                    'recordsTotal': 0,
                    'recordsFiltered': 0,
                    'draw': int(request.REQUEST.get('draw', 0))
                }


#        logger.info("RET=%s"%ret)
        return ret
Example #36
0
    def emit(self, record):
        try:
            request = record.request

            internal = 'internal' if request.META.get('REMOTE_ADDR') in \
                settings.INTERNAL_IPS else 'EXTERNAL'

            subject = '{} ({} IP): {}'.format(
                record.levelname,
                internal,
                record.getMessage(),
            )
        except Exception:
            subject = '{}: {}'.format(
                record.levelname,
                record.getMessage(),
            )
            request = None
        subject = self.format_subject(subject)

        # Since we add a nicely formatted traceback on our own, create a copy
        # of the log record without the exception data.
        no_exc_record = copy.copy(record)
        no_exc_record.exc_info = None
        no_exc_record.exc_text = None

        if record.exc_info:
            exc_info = record.exc_info
        else:
            exc_info = (None, record.getMessage(), None)

        reporter = ExceptionReporter(request, is_email=True, *exc_info)

        try:
            tb = reporter.get_traceback_text()
        except:
            tb = "(An exception occured when getting the traceback text)"

            if reporter.exc_type:
                tb = "{} (An exception occured when rendering the " \
                    "traceback)".format(reporter.exc_type.__name__)

        message = "{}\n\n{}".format(self.format(no_exc_record), tb)

        colors = {
            'ERROR': 'danger',
            'WARNING': 'warning',
            'INFO': 'good',
        }

        attachments = {
            'title': subject,
            'text': message,
            'color': colors.get(record.levelname, '#AAAAAA'),
        }

        attachments.update(self.kwargs)

        self.send_message(self.template, {'text': subject},
                          self.generate_attachments(**attachments),
                          channel=self.channel)
Example #37
0
    def error_handler(self, e, request, meth, em_format):
        """
        Override this method to add handling of errors customized for your
        needs
        """
        if isinstance(e, FormValidationError):
            return self.form_validation_response(
                e, self.determine_emitter(request))

        elif isinstance(e, TypeError):
            result = rc.BAD_REQUEST

            msg = 'Method signature does not match.\n\n'

            try:
                hm = HandlerMethod(meth)
                sig = hm.signature

            except TypeError:
                msg += 'Signature could not be determined'

            else:
                if sig:
                    msg += 'Signature should be: %s' % sig
                else:
                    msg += 'Resource does not expect any parameters.'

            if self.display_errors:
                msg += '\n\nException was: %s' % str(e)

            result.content = format_error(msg)
            return result
        elif isinstance(e, Http404):
            return rc.NOT_FOUND

        elif isinstance(e, HttpStatusCode):
            return e.response

        else:
            """
            On errors (like code errors), we'd like to be able to
            give crash reports to both admins and also the calling
            user. There's two setting parameters for this:

            Parameters::
             - `PISTON_EMAIL_ERRORS`: Will send a Django formatted
               error email to people in `settings.ADMINS`.
             - `PISTON_DISPLAY_ERRORS`: Will return a simple traceback
               to the caller, so he can tell you what error they got.

            If `PISTON_DISPLAY_ERRORS` is not enabled, the caller will
            receive a basic "500 Internal Server Error" message.
            """
            exc_type, exc_value, tb = sys.exc_info()
            rep = ExceptionReporter(request, exc_type, exc_value, tb.tb_next)
            if self.email_errors:
                self.email_exception(rep)
            if self.display_errors:
                return HttpResponseServerError(
                    format_error('\n'.join(rep.format_exception())))
            else:
                raise
Example #38
0
 def __init__(self, request, exc_type, exc_value, frames):
     ExceptionReporter.__init__(self, request, exc_type, exc_value, None)
     self.frames = frames
Example #39
0
    def create_from_exception(self, exc_info=None, **kwargs):
        """
        Creates an error log from an exception.
        """
        if not exc_info:
            exc_info = sys.exc_info()
        exc_type, exc_value, exc_traceback = exc_info

        def to_unicode(f):
            if isinstance(f, dict):
                nf = dict()
                for k, v in f.iteritems():
                    nf[str(k)] = to_unicode(v)
                f = nf
            elif isinstance(f, (list, tuple)):
                f = [to_unicode(f) for f in f]
            else:
                try:
                    f = smart_unicode(f)
                except (UnicodeEncodeError, UnicodeDecodeError):
                    f = '(Error decoding value)'
                except Exception:  # in some cases we get a different exception
                    f = smart_unicode(type(f))
            return f

        def shorten(var):
            if not isinstance(var, basestring):
                var = to_unicode(var)
            if len(var) > 200:
                var = var[:200] + '...'
            return var

        reporter = ExceptionReporter(None, exc_type, exc_value, exc_traceback)
        frames = varmap(shorten, reporter.get_traceback_frames())

        if not kwargs.get('view'):
            # This should be cached
            modules = get_installed_apps()
            if settings.INCLUDE_PATHS:
                modules = set(list(modules) + settings.INCLUDE_PATHS)

            def iter_tb_frames(tb):
                while tb:
                    yield tb.tb_frame
                    tb = tb.tb_next

            def contains(iterator, value):
                for k in iterator:
                    if value.startswith(k):
                        return True
                return False

            # We iterate through each frame looking for an app in INSTALLED_APPS
            # When one is found, we mark it as last "best guess" (best_guess) and then
            # check it against SENTRY_EXCLUDE_PATHS. If it isnt listed, then we
            # use this option. If nothing is found, we use the "best guess".
            best_guess = None
            for frame in iter_tb_frames(exc_traceback):
                view = '.'.join(
                    [frame.f_globals['__name__'], frame.f_code.co_name])
                if contains(modules, view):
                    if not (contains(settings.EXCLUDE_PATHS, view)
                            and best_guess):
                        best_guess = view
                elif best_guess:
                    break
            if best_guess:
                view = best_guess

            kwargs['view'] = view

        data = kwargs.pop('data', {}) or {}
        data['__sentry__'] = {
            'exc':
            map(to_unicode,
                [exc_type.__class__.__module__, exc_value.args, frames]),
        }

        if isinstance(exc_value, TemplateSyntaxError) and hasattr(
                exc_value, 'source'):
            origin, (start, end) = exc_value.source
            data['__sentry__'].update({
                'template': (origin.reload(), start, end, origin.name),
            })
            kwargs['view'] = origin.loadname

        tb_message = '\n'.join(
            traceback.format_exception(exc_type, exc_value, exc_traceback))

        kwargs.setdefault('message', to_unicode(exc_value))

        return self.process(class_name=exc_type.__name__,
                            traceback=tb_message,
                            data=data,
                            **kwargs)
Example #40
0
 def test_request_with_items_key(self):
     """
     An exception report can be generated for requests with 'items' in
     request GET, POST, FILES, or COOKIES QueryDicts.
     """
     value = '<td>items</td><td class="code"><pre>&#39;Oops&#39;</pre></td>'
     # GET
     request = self.rf.get('/test_view/?items=Oops')
     reporter = ExceptionReporter(request, None, None, None)
     html = reporter.get_traceback_html()
     self.assertInHTML(value, html)
     # POST
     request = self.rf.post('/test_view/', data={'items': 'Oops'})
     reporter = ExceptionReporter(request, None, None, None)
     html = reporter.get_traceback_html()
     self.assertInHTML(value, html)
     # FILES
     fp = StringIO('filecontent')
     request = self.rf.post('/test_view/', data={'name': 'filename', 'items': fp})
     reporter = ExceptionReporter(request, None, None, None)
     html = reporter.get_traceback_html()
     self.assertInHTML(
         '<td>items</td><td class="code"><pre>&lt;InMemoryUploadedFile: '
         'items (application/octet-stream)&gt;</pre></td>',
         html
     )
     # COOKES
     rf = RequestFactory()
     rf.cookies['items'] = 'Oops'
     request = rf.get('/test_view/')
     reporter = ExceptionReporter(request, None, None, None)
     html = reporter.get_traceback_html()
     self.assertInHTML('<td>items</td><td class="code"><pre>&#39;Oops&#39;</pre></td>', html)
Example #41
0
    def log_event(cls, request, response=None, exception=None):
        from django.views.debug import ExceptionReporter

        stack_info = {}
        if exception:
            exc_type, exc_value, exc_traceback = sys.exc_info()
            summary = "{0}: {1}".format(exception.__class__.__name__, unicode(exception))
            lineno = traceback.tb_lineno(exc_traceback)

            stack = traceback.extract_tb(exc_traceback)
            unique_path = "|".join(line[0] for line in stack)
            path = stack[-1][0]

            try:
                reporter = ExceptionReporter(request, is_email=False, *(exc_type, exc_value, exc_traceback))
                django_data = reporter.get_traceback_data()

                stack_info["frames"] = django_data.get("frames", [])

                #Traceback objects aren't JSON serializable, so delete them
                for frame in stack_info["frames"]:
                    if "tb" in frame:
                        del frame["tb"]

                stack_info["lastframe"] = django_data.get("lastframe", {})
            except Exception:
                logging.exception("Unable to get html traceback info for some reason")
            level = EVENT_LEVEL_ERROR

        else:
            summary = "{0} at {1}".format(response.status_code, request.path)
            lineno = 0
            path = "?".join([request.path, request.META.get('QUERY_STRING')])
            unique_path = path
            exception = HttpResponse()
            level = EVENT_LEVEL_WARNING if response.status_code == 404 else EVENT_LEVEL_INFO

        exception_name = exception.__class__.__name__

        # unique_path is either the full URL or the combined paths from the
        # entire stack trace.
        path_hash = Error.hash_for_file_path(unique_path)

        #We try to get from the cache first because on the App Engine datastore
        #we'll get screwed by eventual consistency otherwise
        CACHE_KEY = "|".join([exception_name, path_hash, str(lineno)])
        error = cache.get(CACHE_KEY)
        if error:
            created = False
        else:
            try:
                error, created = Error.objects.get_or_create(
                    exception_class_name=exception_name,
                    hashed_file_path=path_hash,
                    line_number=lineno,
                    defaults={
                        'file_path': path,
                        'level': level,
                        'summary': summary,
                        'exception_class_name': exception.__class__.__name__ if exception else ""
                    }
                )
            except MultipleObjectsReturned:
                #FIXME: Temporary hack for App Engine If we created dupes, this de-dupes them
                errors = Error.objects.filter(exception_class_name=exception_name, hashed_file_path=path_hash, line_number=lineno).all()

                max_errors = 0
                to_keep = None
                to_remove = []
                for error in errors:
                    num_events = error.events.count()
                    if max_errors < num_events:
                        # Store the error with the most events
                        to_keep = error
                        max_errors = num_events
                    else:
                        #this error doesn't have the most events, so mark it for removal
                        to_remove.append(error)

                assert to_keep

                logging.warning("Removing {} duplicate errors".format(len(to_remove)))
                for error in to_remove:
                    error.events.all().update(error=to_keep)
                    error.delete()

                error = to_keep

            cache.set(CACHE_KEY, error)

        @db.transactional(xg=True)
        def txn(_error):
            _error = Error.objects.get(pk=_error.pk)

            event = Event.objects.create(
                error=_error,
                request_repr=repr(request).strip(),
                request_method=request.method,
                request_url=request.build_absolute_uri(),
                request_querystring=request.META['QUERY_STRING'],
                logged_in_user_email=getattr(getattr(request, "user", None), "email", ""),
                stack_info_json=json.dumps(stack_info),
                app_version=os.environ.get('CURRENT_VERSION_ID', 'Unknown'),
                request_json=construct_request_json(request)
            )

            _error.last_event = timezone.now()
            _error.event_count += 1
            _error.save()
            return event

        return txn(error)
Example #42
0
 def test_request_with_items_key(self):
     """
     An exception report can be generated for requests with 'items' in
     request GET, POST, FILES, or COOKIES QueryDicts.
     """
     # GET
     request = self.rf.get('/test_view/?items=Oops')
     reporter = ExceptionReporter(request, None, None, None)
     text = reporter.get_traceback_text()
     self.assertIn("items = 'Oops'", text)
     # POST
     request = self.rf.post('/test_view/', data={'items': 'Oops'})
     reporter = ExceptionReporter(request, None, None, None)
     text = reporter.get_traceback_text()
     self.assertIn("items = 'Oops'", text)
     # FILES
     fp = StringIO('filecontent')
     request = self.rf.post('/test_view/', data={'name': 'filename', 'items': fp})
     reporter = ExceptionReporter(request, None, None, None)
     text = reporter.get_traceback_text()
     self.assertIn('items = <InMemoryUploadedFile:', text)
     # COOKES
     rf = RequestFactory()
     rf.cookies['items'] = 'Oops'
     request = rf.get('/test_view/')
     reporter = ExceptionReporter(request, None, None, None)
     text = reporter.get_traceback_text()
     self.assertIn("items = 'Oops'", text)
Example #43
0
 def test_disallowed_host(self):
     "An exception report can be generated even for a disallowed host."
     request = self.rf.get('/', HTTP_HOST='evil.com')
     reporter = ExceptionReporter(request, None, None, None)
     text = reporter.get_traceback_text()
     self.assertIn("http://evil.com/", text)
Example #44
0
 def test_message_only(self):
     reporter = ExceptionReporter(None, None, "I'm a little teapot", None)
     reporter.get_traceback_text()
Example #45
0
    def emit(self, record):
        if not switch_is_active("LOG_TO_DISCORD"):
            return

        try:
            request = record.request
            subject = "%s (%s IP): %s" % (
                record.levelname,
                ("internal" if request.META.get("REMOTE_ADDR")
                 in settings.INTERNAL_IPS else "EXTERNAL"),
                record.getMessage(),
            )
        except Exception:
            subject = "%s: %s" % (record.levelname, record.getMessage())
            request = None

        subject = subject.replace("\n", "\\n").replace("\r", "\\r")

        if record.exc_info:
            exc_info = record.exc_info
        else:
            exc_info = (None, record.getMessage(), None)

        reporter = ExceptionReporter(request, *exc_info)
        data = reporter.get_traceback_data()

        location = f" at {request.path_info}" if request else ""
        heading = f"{data.get('exception_type', 'Report')}{location}"
        exception_value = data.get("exception_value",
                                   "No exception message supplied")
        fields = [
            {
                "name": "Subject",
                "value": subject,
                "inline": True
            },
            {
                "name": heading,
                "value": exception_value,
                "inline": False
            },
        ]

        if request:
            if request.GET != {}:
                fields.append({
                    "name": "GET parameters",
                    "value": str(dict(request.GET)),
                    "inline": False,
                })
            if request.POST != {}:
                fields.append({
                    "name": "POST parameters",
                    "value": str(dict(request.POST)),
                    "inline": False,
                })

        json = {
            "embeds": [{
                "title": "SC2 Ladder Exception",
                "fields": fields,
                "footer": {
                    "text": ""
                },
            }]
        }

        requests.post(settings.DISCORD_WEBHOOK, json=json)
Example #46
0
    def create_from_exception(self, exc_info=None, **kwargs):
        """
        Creates an error log from an exception.
        """
        if not exc_info:
            exc_info = sys.exc_info()

        exc_type, exc_value, exc_traceback = exc_info

        reporter = ExceptionReporter(None, exc_type, exc_value, exc_traceback)
        frames = varmap(shorten, reporter.get_traceback_frames())

        if not kwargs.get('view'):
            # This should be cached
            modules = get_installed_apps()
            if settings.INCLUDE_PATHS:
                modules = set(list(modules) + settings.INCLUDE_PATHS)

            def iter_tb_frames(tb):
                while tb:
                    yield tb.tb_frame
                    tb = tb.tb_next

            def contains(iterator, value):
                for k in iterator:
                    if value.startswith(k):
                        return True
                return False

            # We iterate through each frame looking for an app in INSTALLED_APPS
            # When one is found, we mark it as last "best guess" (best_guess) and then
            # check it against SENTRY_EXCLUDE_PATHS. If it isnt listed, then we
            # use this option. If nothing is found, we use the "best guess".
            best_guess = None
            view = None
            for frame in iter_tb_frames(exc_traceback):
                try:
                    view = '.'.join(
                        [frame.f_globals['__name__'], frame.f_code.co_name])
                except:
                    continue
                if contains(modules, view):
                    if not (contains(settings.EXCLUDE_PATHS, view)
                            and best_guess):
                        best_guess = view
                elif best_guess:
                    break
            if best_guess:
                view = best_guess

            if view:
                kwargs['view'] = view

        data = kwargs.pop('data', {}) or {}
        if hasattr(exc_type, '__class__'):
            exc_module = exc_type.__class__.__module__
        else:
            exc_module = None
        data['__sentry__'] = {
            'exc': map(transform, [exc_module, exc_value.args, frames]),
        }

        if (isinstance(exc_value, TemplateSyntaxError) and \
            isinstance(getattr(exc_value, 'source', None), (tuple, list)) and isinstance(exc_value.source[0], LoaderOrigin)):
            origin, (start, end) = exc_value.source
            data['__sentry__'].update({
                'template': (origin.reload(), start, end, origin.name),
            })
            kwargs['view'] = origin.loadname

        tb_message = '\n'.join(
            traceback.format_exception(exc_type, exc_value, exc_traceback))

        kwargs.setdefault('message', transform(force_unicode(exc_value)))

        return self.process(class_name=exc_type.__name__,
                            traceback=tb_message,
                            data=data,
                            **kwargs)
Example #47
0
 def process_exception(self, request, exception):
     exc_type, exc_value, tb = sys.exc_info()
     reporter = ExceptionReporter(request, exc_type, exc_value, tb)
     html = reporter.get_traceback_html()
     return HttpResponse(html, status=500, content_type='text/html')
Example #48
0
def get_exception_info(request):
    # We use Django's debug reporter, even though we are doing our own template.
    # This is because it has a great way of collecting all the useful info we
    # need, so no reason not to leverage it
    exc_info = sys.exc_info()
    reporter = ExceptionReporter(request, *exc_info)
    ctx = reporter.get_traceback_data()

    # This is a refactor of what the technical_500_template contains, just
    # doing the logic in Python rather than in a template. We collect all this
    # information so that we can log it.
    exception_type = ctx[
        'exception_type'] if 'exception_type' in ctx else "No exception supplied"
    exception_value = ctx[
        'exception_value'] if 'exception_value' in ctx else "No exception supplied"
    django_version = ctx["django_version_info"]
    python_executable = ctx['sys_executable']
    python_version = ctx['sys_version_info']
    python_path = ctx['sys_path']
    server_time = str(ctx['server_time'])
    unicode_hint = None
    if 'unicode_hint' in ctx:
        unicdoe_hint = ctx['unicode_hint']
    last_frame = None
    if 'lastframe' in ctx:
        frame_info = ctx['lastframe']
        last_frame = "%s in %s, line %s" % (frame_info['filename'],
                                            frame_info['function'],
                                            frame_info['lineno'])
    loaders = []
    if 'template_does_not_exist' in ctx and 'loader_debug_info' in ctx and ctx[
            'loader_debug_info']:
        for loader in ctx['loader_debug_info']:
            loader_info = {"name": loader['loader'], "templates": []}
            for tmpl in loader['templates']:
                loader_info['templates'].append({
                    "file": tmpl['name'],
                    "exists": tmpl['exists']
                })
            loaders.append(loader_info)
    template_errors = None
    if 'template_info' in ctx and ctx['template_info']:
        template_info = ctx['template_info']
        template_errors = {
            "name": template_info['name'],
            "line": template_info['line'],
            "message": template_info['message']
        }
    exception_info = []
    if 'frames' in ctx:
        frames = ctx['frames']
        for frame in frames:
            frame_info = {
                "filename": frame['filename'],
                "function": frame['function'],
                "line": frame['lineno'],
                "context_line": frame['context_line'],
                "vars": []
            }
            if 'vars' in frame:
                for var in frame['vars']:
                    frame_info['vars'].append({
                        "variable": str(var[0]),
                        "value": format(var[1])
                    })
            exception_info.append(frame_info)
    request_info = {
        "path_info": request.path_info,
        "method": request.META['REQUEST_METHOD'],
        "url": request.build_absolute_uri(),
        "GET": {},
        "POST": {},
        "FILES": {},
        "COOKIES": {},
        "META": {}
    }
    if hasattr(request, "GET"):
        for key, value in request.GET.iteritems():
            request_info['GET'][key] = format(value)
    if "filtered_POST" in ctx:
        for key, value in ctx['filtered_POST'].iteritems():
            request_info['POST'][key] = format(value)
    if hasattr(request, "FILES"):
        for key, value in request.FILES.iteritems():
            request_info['FILES'][key] = format(value)
    if hasattr(request, "COOKIES"):
        for key, value in request.COOKIES.iteritems():
            request_info['COOKIES'][key] = format(value)
    if hasattr(request, "META"):
        for key, value in request.META.iteritems():
            request_info['META'][key] = format(value)
    settings_info = {}
    for key, value in ctx['settings'].iteritems():
        settings_info[key] = format(value)

    ctx['errorid'] = errorid = uuid.uuid4().hex

    full_info = dict(__time=datetime.datetime.now().isoformat(),
                     __uuid=errorid,
                     settings=settings_info,
                     request=request_info,
                     traceback=exception_info,
                     stack=traceback.format_exc(exc_info[2]),
                     last_frame=last_frame,
                     template_loaders=loaders,
                     template_errors=template_errors,
                     unicode_hint=unicdoe_hint,
                     exception_type=exception_type,
                     exception_value=exception_value,
                     django_version=django_version,
                     python_version=python_version,
                     python_executable=python_executable,
                     python_path=python_path,
                     server_time=server_time)

    return (errorid, ctx, full_info)
 def test_no_exception(self):
     "An exception report can be generated for just a request"
     request = self.rf.get('/test_view/')
     reporter = ExceptionReporter(request, None, None, None)
     text = reporter.get_traceback_text()
Example #50
0
    def emit(self, record, *args, **kwargs):
        # original AdminEmailHandler "emit" method code (but without actually sending email)
        try:
            request = record.request
            subject = '%s (%s IP): %s' % (record.levelname, (
                'internal' if request.META.get('REMOTE_ADDR')
                in settings.INTERNAL_IPS else 'EXTERNAL'), record.getMessage())
        except Exception:
            subject = '%s: %s' % (record.levelname, record.getMessage())
            request = None
        subject = self.format_subject(subject)

        # Since we add a nicely formatted traceback on our own, create a copy
        # of the log record without the exception data.
        no_exc_record = copy(record)
        no_exc_record.exc_info = None
        no_exc_record.exc_text = None

        if record.exc_info:
            exc_info = record.exc_info
        else:
            exc_info = (None, record.getMessage(), None)

        reporter = ExceptionReporter(request, is_email=True, *exc_info)
        message = "%s\n\n%s" % (self.format(no_exc_record),
                                reporter.get_traceback_text())
        html_message = reporter.get_traceback_html(
        ) if self.include_html else None

        #self.send_mail(subject, message, fail_silently=True, html_message=html_message)

        # this is where original "emit" method code ends

        # construct slack attachment detail fields
        attachments = [
            {
                'title':
                subject,
                'color':
                'danger',
                'fields': [
                    {
                        "title": "Level",
                        "value": record.levelname,
                        "short": True,
                    },
                    {
                        "title": "Method",
                        "value": request.method if request else 'No Request',
                        "short": True,
                    },
                    {
                        "title": "Path",
                        "value": request.path if request else 'No Request',
                        "short": True,
                    },
                    {
                        "title":
                        "User",
                        "value":
                        ((request.user.username + ' (' + str(request.user.pk) +
                          ')' if request.user.is_authenticated else
                          'Anonymous') if request else 'No Request'),
                        "short":
                        True,
                    },
                    {
                        "title": "Status Code",
                        "value": record.status_code,
                        "short": True,
                    },
                    {
                        "title":
                        "UA",
                        "value": (request.META['HTTP_USER_AGENT'] if request
                                  and request.META else 'No Request'),
                        "short":
                        False,
                    },
                    {
                        "title": 'GET Params',
                        "value":
                        json.dumps(request.GET) if request else 'No Request',
                        "short": False,
                    },
                    {
                        "title": "POST Data",
                        "value":
                        json.dumps(request.POST) if request else 'No Request',
                        "short": False,
                    },
                ],
            },
        ]

        # add main error message body

        # slack message attachment text has max of 8000 bytes
        # lets split it up into 7900 bytes long chunks to be on the safe side

        split = 7900
        parts = range(math.ceil(len(message.encode('utf8')) / split))

        for part in parts:

            start = 0 if part == 0 else split * part
            end = split if part == 0 else split * part + split

            # combine final text and prepend it with line breaks
            # so the details in slack message will fully collapse
            detail_text = '\r\n\r\n\r\n\r\n\r\n\r\n\r\n' + message[start:end]

            attachments.append({
                'color': 'danger',
                'title': 'Details (Part {})'.format(part + 1),
                'text': detail_text,
                'ts': time.time(),
            })

        # construct main text
        main_text = 'Error at ' + time.strftime("%A, %d %b %Y %H:%M:%S +0000",
                                                time.gmtime())

        # construct data
        data = {
            'payload':
            json.dumps({
                'main_text': main_text,
                'attachments': attachments
            }),
        }

        # setup channel webhook
        webhook_url = settings.SLACK_WEBHOOK_URL

        # send it

        def func():
            requests.post(webhook_url, data=data)

        r = asyncExec(func)
 def test_request_and_message(self):
     "A message can be provided in addition to a request"
     request = self.rf.get('/test_view/')
     reporter = ExceptionReporter(request, None, "I'm a little teapot",
                                  None)
     text = reporter.get_traceback_text()
Example #52
0
 def wrapped_contest_view(request, contestid=None, **kwargs):
     try:
         token_container.set_token(
             request.COOKIES.get(settings.SATORI_TOKEN_COOKIE_NAME, ''))
     except:
         token_container.set_token('')
     page_info = None
     try:
         if contestid is not None:
             try:
                 page_info = Web.get_page_info(Contest(int(contestid)))
             except:
                 page_info = Web.get_page_info()
                 raise
         else:
             page_info = Web.get_page_info()
         page_info.url = urlquote(request.path)
         res = func(request, page_info, **kwargs)
         if request.COOKIES.get(settings.SATORI_TOKEN_COOKIE_NAME,
                                '') != token_container.get_token():
             res.set_cookie(settings.SATORI_TOKEN_COOKIE_NAME,
                            token_container.get_token(),
                            domain=settings.SATORI_TOKEN_COOKIE_DOMAIN,
                            path=settings.SATORI_TOKEN_COOKIE_PATH,
                            secure=settings.SATORI_TOKEN_COOKIE_SECURE
                            or None,
                            httponly=settings.SATORI_TOKEN_COOKIE_HTTPONLY
                            or None)
         return res
     except (TokenInvalid, TokenExpired):
         res = HttpResponseRedirect(
             reverse('login') + '?redir=' + urlquote(request.path))
         res.set_cookie(settings.SATORI_TOKEN_COOKIE_NAME, '')
         return res
     except AccessDenied:
         if page_info and not page_info.role:
             return HttpResponseRedirect(
                 reverse('login') + '?redir=' + urlquote(request.path))
         if request.method == 'POST':
             info = 'You don\'t have rights to perform the requested action.'
         else:
             info = 'You don\'t have rights to view the requested object.'
         res = render_to_response('error.html', {
             'page_info': page_info,
             'message': 'Access denied',
             'info': info
         })
         res.status_code = 403
         return res
     except ArgumentNotFound:
         res = render_to_response(
             'error.html', {
                 'page_info': page_info,
                 'message': 'Object not found',
                 'info': 'The requested object does not exist.'
             })
         res.status_code = 404
         return res
     except TTransportException:
         res = render_to_response(
             'error.html', {
                 'page_info': page_info,
                 'message': 'Server error',
                 'info': 'Communication with the core server failed.'
             })
         res.status_code = 500
         return res
     except Exception as e:
         traceback.print_exc()
         if settings.DEBUG:
             reporter = ExceptionReporter(request, *sys.exc_info())
             detail = reporter.get_traceback_html()
             detail2 = []
             in_style = False
             for line in detail.split('\n'):
                 if line.startswith('  </style'):
                     in_style = False
                 if line == '    #summary { background: #ffc; }':
                     line = '    #summary { background: #eee; }'
                 if in_style:
                     line = '  #content ' + line
                 if line.startswith('  <style'):
                     in_style = True
                 detail2.append(line)
             detail = '\n'.join(detail2)
         else:
             detail = ''
         res = render_to_response(
             'error.html', {
                 'page_info': page_info,
                 'message': 'Internal server error',
                 'info': 'The server encountered an internal error.',
                 'detail': detail
             })
         res.status_code = 500
         return res