Пример #1
0
    def testSignalsWithoutRequest(self):
        request = RF.get("/", REMOTE_ADDR="127.0.0.1:8000")

        try:
            Message.objects.get(id=999999999)
        except Message.DoesNotExist, exc:
            got_request_exception.send(sender=self.__class__, request=None)
Пример #2
0
def custom_exception_handler(exc):
    """
    Custom exception handler for DRF, which doesn't provide one for HTTP
    responses like tastypie does.
    """
    # Call REST framework's default exception handler first,
    # to get the standard error response.
    response = exception_handler(exc)

    # If the response is None, then DRF didn't handle the exception and we
    # should do it ourselves.
    if response is None:
        # Start with a generic default error message.
        data = {"detail": "Internal Server Error"}

        # Include traceback if DEBUG is active.
        if settings.DEBUG:
            import traceback
            import sys

            data['error_message'] = unicode(exc)
            data['traceback'] = '\n'.join(
                traceback.format_exception(*(sys.exc_info())))

        request = getattr(exc, '_request', None)
        klass = getattr(exc, '_klass', None)

        # Send the signal so other apps are aware of the exception.
        got_request_exception.send(klass, request=request)

        # Send the 500 response back.
        response = Response(data, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    return response
Пример #3
0
        def _wrapped(request, *args, **kwargs):
            try:
                status = 200
                headers = {
                        'Access-Control-Allow-Origin': '*',
                    }

                if len(methods) > 0 and request.method not in methods:
                    data = http.HttpResponseNotAllowed('')
                else:
                    # Call the view
                    data = func(request, *args, **kwargs)

                # Isn't thrown as an exception, but instead returned
                if isinstance(data, http.HttpResponseNotAllowed):
                    return http.HttpResponse(dumps({
                            'error': 405,
                            'msg': 'HTTP method not allowed.',
                        }), status=405, content_type='application/json')

                # Allow for multiple results
                if isinstance(data, tuple):
                    if len(data) == 2:
                        data, status = data
                    elif len(data) == 3:
                        data, status, headers = data
                    else:
                        raise Exception('Too many return values from view')

                if not isinstance(data, dict):
                    raise Exception('Expected dictionary')

                resp = http.HttpResponse(dumps(data), status=status, content_type='application/json')
                for h in headers:
                    resp[h] = headers[h]

            except Exception as e:
                if isinstance(e, BadRequest):
                    resp = http.HttpResponseBadRequest(dumps({
                            'error': 400,
                            'msg': str(e),
                        }), content_type='application/json')
                elif isinstance(e, PermissionDenied):
                    resp = http.HttpResponseForbidden(dumps({
                            'error': 403,
                            'msg': str(e),
                        }), content_type='application/json')
                elif isinstance(e, http.Http404):
                    resp = http.HttpResponseNotFound(dumps({
                            'error': 404,
                            'msg': str(e),
                        }), content_type='application/json')
                else:
                    got_request_exception.send(sender=BaseHandler, request=request)
                    resp = http.HttpResponseServerError(dumps({
                            'error': 500,
                            'msg': 'Internal server error.',
                        }), content_type='application/json')

            return resp
Пример #4
0
 def process_exception(self, request, exception):
     if isinstance(exception, RecordModifiedError):
         got_request_exception.send(sender=self, request=request)
         callback = get_callable(conf.HANDLER409)
         return callback(request, target=exception.target)
     else:  # pragma: no cover
         pass
Пример #5
0
    def testSignalsWithoutRequest(self):
        request = RF.get("/", REMOTE_ADDR="127.0.0.1:8000")

        try:
            Message.objects.get(id=999999999)
        except Message.DoesNotExist, exc:
            got_request_exception.send(sender=self.__class__, request=None)
Пример #6
0
 def process_exception(self, request, exception):
     if isinstance(exception, RecordModifiedError):
         got_request_exception.send(sender=self, request=request)
         callback = get_callable(conf.HANDLER409)
         return callback(request, target=exception.target)
     else:  # pragma: no cover
         pass
Пример #7
0
def custom_exception_handler(exc):
    """
    Custom exception handler for DRF, which doesn't provide one for HTTP
    responses like tastypie does.
    """
    # Call REST framework's default exception handler first,
    # to get the standard error response.
    response = exception_handler(exc)

    # If the response is None, then DRF didn't handle the exception and we
    # should do it ourselves.
    if response is None:
        # Start with a generic default error message.
        data = {"detail": "Internal Server Error"}

        # Include traceback if DEBUG is active.
        if settings.DEBUG:
            import traceback
            import sys

            data['error_message'] = unicode(exc)
            data['traceback'] = '\n'.join(
                traceback.format_exception(*(sys.exc_info())))

        request = getattr(exc, '_request', None)
        klass = getattr(exc, '_klass', None)

        # Send the signal so other apps are aware of the exception.
        got_request_exception.send(klass, request=request)

        # Send the 500 response back.
        response = Response(data, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    return response
Пример #8
0
    def test_signal_integration(self):
        with Settings(METLOG_CONF=self.METLOG_CONF,
                      METLOG=self.METLOG,
                      SENTRY_CLIENT=self.SENTRY_CLIENT,
                      SENTRY_DSN=DSN):

            self.raven = get_client()

            try:
                int('hello')
            except:
                got_request_exception.send(sender=self.__class__, request=None)
            else:
                self.fail('Expected an exception.')

            msgs = settings.METLOG.sender.msgs

            self.assertEquals(len(msgs), 1)

            event = self.raven.decode(json.loads(msgs[0])['payload'])
            self.assertTrue('sentry.interfaces.Exception' in event)
            exc = event['sentry.interfaces.Exception']
            self.assertEquals(exc['type'], 'ValueError')
            self.assertEquals(exc['value'], u"invalid literal for int() with base 10: 'hello'")
            self.assertEquals(event['level'], logging.ERROR)
            self.assertEquals(event['message'], u"ValueError: invalid literal for int() with base 10: 'hello'")
            self.assertEquals(event['culprit'], 'tests.contrib.django.tests.test_signal_integration')

            # The project_id must be extracted from the SENTRY_DSN
            # option
            self.assertEquals(event['project'],
                    str(TESTING_PROJECT_ID))
Пример #9
0
def custom_exception_handler(exc, context=None):
    """
    Custom exception handler for DRF, which ensures every exception we throw
    is caught, returned as a nice DRF Response, while still going to sentry
    etc.

    The default DRF exception handler does some of this work already, but it
    lets non-api exceptions through, and we don't want that.
    """
    # If propagate is true, bail early.
    if settings.DEBUG_PROPAGATE_EXCEPTIONS:
        raise

    # Call REST framework's default exception handler first,
    # to get the standard error response.
    response = exception_handler(exc, context)

    # If the response is None, then DRF didn't handle the exception and we
    # should do it ourselves.
    if response is None:
        # Start with a generic default error message.
        data = {'detail': 'Internal Server Error'}

        # Send the got_request_exception signal so other apps like sentry
        # are aware of the exception. The sender does not match what a real
        # exception would do (we don't have access to the handler here) but it
        # should not be an issue, what matters is the request.
        request = context.get('request')
        sender = context.get('view').__class__
        got_request_exception.send(sender, request=request)

        # Send the 500 response back.
        response = Response(data, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    return response
Пример #10
0
    def testSignalsWithoutRequest(self):
        Error.objects.all().delete()
        ErrorBatch.objects.all().delete()

        request = RF.get("/", REMOTE_ADDR="127.0.0.1:8000")

        try:
            Error.objects.get(id=999999999)
        except Error.DoesNotExist, exc:
            got_request_exception.send(sender=self.__class__, request=None)
Пример #11
0
    def testSignalsWithoutRequest(self):
        Error.objects.all().delete()
        ErrorBatch.objects.all().delete()

        request = RF.get("/", REMOTE_ADDR="127.0.0.1:8000")

        try:
            Error.objects.get(id=999999999)
        except Error.DoesNotExist, exc:
            got_request_exception.send(sender=self.__class__, request=None)
Пример #12
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)
        got_request_exception.send(sender=type(self), request=request)
        if isinstance(e, TypeError):
            result = rc.BAD_REQUEST
            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)

            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
Пример #13
0
    def testIntegrityMessage(self):
        DuplicateKeyModel.objects.create()
        try:
            DuplicateKeyModel.objects.create()
        except:
            got_request_exception.send(sender=self.__class__)
        else:
            self.fail('Excepted an IntegrityMessage to be raised.')

        self.assertEquals(Message.objects.count(), 1)
        self.assertEquals(GroupedMessage.objects.count(), 1)
Пример #14
0
    def process_exception(self, request, exception):
        got_request_exception.send(sender=self, request=request)

        if not self.should_log(request):
            return None

        page_request = self.get_existing_page_request(request)

        if self.page_request_is_valid(request, page_request):
            page_request.was_exception = True
            page_request.save()
Пример #15
0
    def testIntegrityMessage(self):
        DuplicateKeyModel.objects.create()
        try:
            DuplicateKeyModel.objects.create()
        except:
            got_request_exception.send(sender=self.__class__)
        else:
            self.fail('Excepted an IntegrityMessage to be raised.')

        self.assertEquals(Message.objects.count(), 1)
        self.assertEquals(GroupedMessage.objects.count(), 1)
Пример #16
0
    def testDatabaseMessage(self):
        from django.db import connection
        
        try:
            cursor = connection.cursor()
            cursor.execute("select foo")
        except:
            got_request_exception.send(sender=self.__class__)

        self.assertEquals(Message.objects.count(), 1)
        self.assertEquals(GroupedMessage.objects.count(), 1)
Пример #17
0
    def testDatabaseMessage(self):
        from django.db import connection

        try:
            cursor = connection.cursor()
            cursor.execute("select foo")
        except:
            got_request_exception.send(sender=self.__class__)

        self.assertEquals(Message.objects.count(), 1)
        self.assertEquals(GroupedMessage.objects.count(), 1)
Пример #18
0
    def testIntegrityError(self):
        DuplicateKeyModel.objects.create()
        try:
            DuplicateKeyModel.objects.create()
        except:
            got_request_exception.send(sender=self.__class__)
        else:
            self.fail('Excepted an IntegrityError to be raised.')

        self.assertEquals(Error.objects.count(), 1)
        self.assertEquals(ErrorBatch.objects.count(), 1)
Пример #19
0
 def process_exception(self, request, exception):
     if isinstance(exception, Http404):
         return
     elif isinstance(exception, PermissionDenied):
         return
     elif isinstance(exception, ImproperlyConfigured):
         logger.critical("Site improperly configured", exc_info=True)
     else:
         logger.exception("[500] %s at %s" % (type(exception).__name__, request.path))
         got_request_exception.send(sender=self, request=request)
         return handler500(request, exc_info=sys.exc_info())
Пример #20
0
    def testIntegrityError(self):
        DuplicateKeyModel.objects.create()
        try:
            DuplicateKeyModel.objects.create()
        except:
            got_request_exception.send(sender=self.__class__)
        else:
            self.fail('Excepted an IntegrityError to be raised.')

        self.assertEquals(Error.objects.count(), 1)
        self.assertEquals(ErrorBatch.objects.count(), 1)
Пример #21
0
 def process_exception(self, request, exception):
     if isinstance(exception, Http404):
         return
     elif isinstance(exception, PermissionDenied):
         return
     elif isinstance(exception, ImproperlyConfigured):
         logger.critical("Site improperly configured", exc_info=True)
     else:
         logger.exception("[500] %s at %s" %
                          (type(exception).__name__, request.path))
         got_request_exception.send(sender=self, request=request)
         return handler500(request, exc_info=sys.exc_info())
Пример #22
0
    def test_task_discarded_when_request_failed(
            self, original_apply_async_mock):
        request_started.send(sender=self)
        test_task.delay()
        self._verify_one_task_queued()

        # Simulate a request exception.
        got_request_exception.send(sender=self)
        self._verify_task_empty()

        # Assert the original `apply_async` was not called.
        self.assertEqual(
            original_apply_async_mock.call_count, 0,
            'Unexpected PostRequestTask.original_apply_async call')
Пример #23
0
def test_signal_integration(django_elasticapm_client):
    try:
        int('hello')
    except ValueError:
        got_request_exception.send(sender=None, request=None)

    assert len(django_elasticapm_client.events) == 1
    event = django_elasticapm_client.events.pop(0)['errors'][0]
    assert 'exception' in event
    exc = event['exception']
    assert exc['type'] == 'ValueError'
    assert exc['message'] == u"ValueError: invalid literal for int() with base 10: 'hello'"
    assert event['culprit'] == 'tests.contrib.django.django_tests.test_signal_integration'
    assert event['handled'] is False
Пример #24
0
    def test_signal_integration(self):
        try:
            int('hello')
        except:
            got_request_exception.send(sender=self.__class__, request=None)
        else:
            self.fail('Expected an exception.')

        self.assertEquals(len(self.raven.events), 1)
        event = self.raven.events.pop(0)
        self.assertEquals(event['class_name'], 'ValueError')
        self.assertEquals(event['level'], logging.ERROR)
        self.assertEquals(event['message'], u"invalid literal for int() with base 10: 'hello'")
        self.assertEquals(event['view'], 'tests.contrib.django.tests.test_signal_integration')
Пример #25
0
    def test_signal_integration(self):
        try:
            int('hello')
        except:
            got_request_exception.send(sender=self.__class__, request=None)
        else:
            self.fail('Expected an exception.')

        self.assertEquals(len(self.raven.events), 1)
        event = self.raven.events.pop(0)
        self.assertEquals(event['class_name'], 'ValueError')
        self.assertEquals(event['level'], logging.ERROR)
        self.assertEquals(event['message'], u"invalid literal for int() with base 10: 'hello'")
        self.assertEquals(event['view'], 'tests.contrib.django.tests.test_signal_integration')
Пример #26
0
    def test_task_discarded_when_request_failed(self,
                                                original_apply_async_mock):
        request_started.send(sender=self)
        test_task.delay()
        self._verify_one_task_queued()

        # Simulate a request exception.
        got_request_exception.send(sender=self)
        self._verify_task_empty()

        # Assert the original `apply_async` was not called.
        self.assertEqual(
            original_apply_async_mock.call_count, 0,
            'Unexpected PostRequestTask.original_apply_async call')
Пример #27
0
def exception_reporting(exception: Exception,
                        context: ExceptionContext) -> None:
    """
    Determines which exceptions to report and sends them to Sentry.
    Used through drf-exceptions-hog
    """
    if not isinstance(exception, APIException):
        capture_exception(exception)

        # NOTE: to make sure we get exception tracebacks in test responses, we need
        # to make sure this signal is called. The django test client uses this to
        # pull out the exception traceback.
        #
        # See https://github.com/django/django/blob/ecf87ad513fd8af6e4a6093ed918723a7d88d5ca/django/test/client.py#L714
        got_request_exception.send(sender=None, request=context["request"])
Пример #28
0
    def _handle_500(self, request, exception):
        import traceback
        import sys
        the_trace = '\n'.join(traceback.format_exception(*(sys.exc_info())))
        if settings.DEBUG:
            response_class = TracebackApplicationJsonError
        else:
            response_class = ApplicationJsonError
        response_code = 500

        NOT_FOUND_EXCEPTIONS = (NotFound, ObjectDoesNotExist, Http404)

        if isinstance(exception, NOT_FOUND_EXCEPTIONS):
            if settings.DEBUG:
                response_class = TracebackNotFoundJsonError
            else:
                response_class = NotFoundJsonError
            response_code = 404

        if settings.DEBUG:
            data = {
                "developer_message": sanitize(six.text_type(exception)),
                "traceback": the_trace,
            }
            return self.error_response(request,
                                       None,
                                       response_class=response_class,
                                       **data)

        # When DEBUG is False, send an error message to the admins (unless it's
        # a 404, in which case we check the setting).
        send_broken_links = getattr(settings, 'SEND_BROKEN_LINK_EMAILS', False)

        if not response_code == 404 or send_broken_links:
            log = logging.getLogger('django.request.tastypie')
            log.error('Internal Server Error: %s' % request.path,
                      exc_info=True,
                      extra={
                          'status_code': response_code,
                          'request': request
                      })

        # Send the signal so other apps are aware of the exception.
        got_request_exception.send(self.__class__, request=request)

        return self.error_response(request,
                                   None,
                                   response_class=response_class)
Пример #29
0
    def test_signal_integration(self):
        try:
            int(None)
        except Exception:
            got_request_exception.send(sender=self.__class__, request=None)
        else:
            self.fail('Expected an exception.')

        assert len(self.raven.events) == 1
        event = self.raven.events.pop(0)
        assert 'exception' in event
        exc = event['exception']['values'][-1]
        assert exc['type'] == 'TypeError'
        assert exc['value'], "int() argument must be a string or a number == not 'NoneType'"
        assert event['level'] == logging.ERROR
        assert event['message'], "TypeError: int() argument must be a string or a number == not 'NoneType'"
Пример #30
0
def new(request):
    if request.POST:
        data = request.POST["data"]

        try:
            chart_data = utils.import_chart_data(data)
        except Exception, e:
            utils.save_import_failure(request.user.username, data)
            got_request_exception.send(sender=None, request=request)
            return HttpResponseServerError("Parse error: " + e.message)

        chart = Chart(creator=request.user)
        chart.chart_data = chart_data
        chart.save()

        return redirect(reverse("chart.views.edit", args=[chart.id]))
Пример #31
0
    def test_signal_integration(self):
        try:
            int(None)
        except Exception:
            got_request_exception.send(sender=self.__class__, request=None)
        else:
            self.fail('Expected an exception.')

        assert len(self.raven.events) == 1
        event = self.raven.events.pop(0)
        assert 'exception' in event
        exc = event['exception']['values'][-1]
        assert exc['type'] == 'TypeError'
        assert exc['value'], "int() argument must be a string or a number == not 'NoneType'"
        assert event['level'] == logging.ERROR
        assert event['message'], "TypeError: int() argument must be a string or a number == not 'NoneType'"
Пример #32
0
    def _handle_500(self, request, exception):
        import traceback
        import sys
        the_trace = '\n'.join(traceback.format_exception(*(sys.exc_info())))
        response_class = http.HttpApplicationError
        response_code = 500

        NOT_FOUND_EXCEPTIONS = (NotFound, ObjectDoesNotExist, Http404)

        if isinstance(exception, NOT_FOUND_EXCEPTIONS):
            response_class = HttpResponseNotFound
            response_code = 404


        detailed_data = {
            "error_message": six.text_type(exception),
            "traceback": the_trace,
        }
        self.log.error('_handle_500 error', exc_info=True, extra={'data': detailed_data, 'request': request, 'original_exception': exception})
        if settings.DEBUG:
            return self.error_response(request, detailed_data, response_class=response_class)

        # When DEBUG is False, send an error message to the admins (unless it's
        # a 404, in which case we check the setting).
        send_broken_links = getattr(settings, 'SEND_BROKEN_LINK_EMAILS', False)

        if not response_code == 404 or send_broken_links:
            log = logging.getLogger('django.request.tastypie')
            log.error('Internal Server Error: %s' % request.path, exc_info=True,
                      extra={'status_code': response_code, 'request': request})

        # Send the signal so other apps are aware of the exception.
        got_request_exception.send(self.__class__, request=request)

        # Prep the data going out.
        if 400 <= response_code < 500:
            data = {
                "error_message": six.text_type(exception),
            }

        else:
            data = {
                "error_message": getattr(settings, 'TASTYPIE_CANNED_ERROR',
                    "Sorry, this request could not be processed. Please try again later."),
            }

        return self.error_response(request, data, response_class=response_class)
Пример #33
0
    def test_signal_integration(self):
        try:
            int(None)
        except Exception:
            got_request_exception.send(sender=self.__class__, request=None)
        else:
            self.fail("Expected an exception.")

        assert len(self.raven.events) == 1
        event = self.raven.events.pop(0)
        assert "exception" in event
        exc = event["exception"]["values"][0]
        assert exc["type"] == "TypeError"
        assert exc["value"], "int() argument must be a string or a number == not 'NoneType'"
        assert event["level"] == logging.ERROR
        assert event["message"], "TypeError: int() argument must be a string or a number == not 'NoneType'"
        assert event["culprit"] == "tests.contrib.django.tests in test_signal_integration"
Пример #34
0
    def test_signal_integration(self):
        try:
            int("hello")
        except:
            got_request_exception.send(sender=self.__class__, request=None)
        else:
            self.fail("Expected an exception.")

        self.assertEquals(len(self.raven.events), 1)
        event = self.raven.events.pop(0)
        self.assertTrue("sentry.interfaces.Exception" in event)
        exc = event["sentry.interfaces.Exception"]
        self.assertEquals(exc["type"], "ValueError")
        self.assertEquals(exc["value"], u"invalid literal for int() with base 10: 'hello'")
        self.assertEquals(event["level"], logging.ERROR)
        self.assertEquals(event["message"], u"ValueError: invalid literal for int() with base 10: 'hello'")
        self.assertEquals(event["culprit"], "tests.contrib.django.tests.test_signal_integration")
Пример #35
0
    def test_signal_integration(self):
        try:
            int('hello')
        except:
            got_request_exception.send(sender=self.__class__, request=None)
        else:
            self.fail('Expected an exception.')

        self.assertEquals(len(self.raven.events), 1)
        event = self.raven.events.pop(0)
        assert 'exception' in event
        exc = event['exception']['values'][0]
        self.assertEquals(exc['type'], 'ValueError')
        self.assertEquals(exc['value'], "invalid literal for int() with base 10: 'hello'")
        self.assertEquals(event['level'], logging.ERROR)
        self.assertEquals(event['message'], "ValueError: invalid literal for int() with base 10: 'hello'")
        self.assertEquals(event['culprit'], 'tests.tests in test_signal_integration')
Пример #36
0
    def test_signal_integration(self):
        try:
            int('hello')
        except:
            got_request_exception.send(sender=self.__class__, request=None)
        else:
            self.fail('Expected an exception.')

        self.assertEquals(len(self.opbeat.events), 1)
        event = self.opbeat.events.pop(0)
        self.assertTrue('exception' in event)
        exc = event['exception']
        self.assertEquals(exc['type'], 'ValueError')
        self.assertEquals(exc['value'], u"invalid literal for int() with base 10: 'hello'")
        self.assertEquals(event['level'], 'error')
        self.assertEquals(event['message'], u"ValueError: invalid literal for int() with base 10: 'hello'")
        self.assertEquals(event['culprit'], 'tests.contrib.django.django_tests.test_signal_integration')
Пример #37
0
    def process_exception(self, request, exception):

        if issubclass(type(exception), ObjectDoesNotExist):
            exception = NotFound(str(exception))

        if has_webargs and issubclass(type(exception), ValidationError):
            exception = BadRequest(exception.messages)

        if not issubclass(type(exception), ApiError):
            return None

        accept_headers = request.META.get('HTTP_ACCEPT', 'application/json')

        doc = Representation(request)
        doc.add_property('message', exception.message)
        if exception.logref is not None:
            doc.add_property('logref', exception.logref)
        if exception.path is not None:
            doc.add_property('path', exception.path)
        if exception.about is not None:
            doc.add_link('about', exception.about)
        if exception.describes is not None:
            doc.add_link('describes', exception.describes)
        if exception.help is not None:
            doc.add_link('help', exception.help)

        # Make sure the exception signal is fired for Sentry, but don't
        # bother it with anything that's not a server error
        if exception.status >= 500:
            got_request_exception.send(sender=self, request=request)

        content_type = best_content_type('vnd.error', accept_headers)

        content = doc.to_json()

        if 'html' in content_type:
            content=create_html(content)

        response = HttpResponse(content=content, status=exception.status)
        response['Content-Type'] = content_type
        response['Vary'] = 'Accept'

        return response
Пример #38
0
    def process_view(self, request, view_func, view_args, view_kwargs):
        try:
            return view_func(request, *view_args, **view_kwargs)
        except GenusTransportError:
            from django.conf import settings

            if settings.DEBUG:
                raise
            else:

                if view_kwargs.get("use_xml", False):
                    template = "social/epic_fail.xml"
                    mimetype = "text/xml"
                else:
                    template = "social/epic_fail.html"
                    mimetype = "text/html"

                got_request_exception.send(sender=self, request=request)

                return direct_to_template(request, template, mimetype=mimetype)
Пример #39
0
    def _handle_500(self, request, exception):
        ''' Override Tastypie for serialization'''
        import traceback
        import sys
        the_trace = '\n'.join(traceback.format_exception(*(sys.exc_info())))
        response_class = HttpApplicationError
        response_code = 500

        NOT_FOUND_EXCEPTIONS = (NotFound, ObjectDoesNotExist, Http404)

        if isinstance(exception, NOT_FOUND_EXCEPTIONS):
            response_class = HttpResponseNotFound
            response_code = 404

        if settings.DEBUG:
            data = {
                "error_message": sanitize(six.text_type(exception)),
                "traceback": the_trace,
            }
            return self.build_error_response(request, data, response_class=response_class)

        # When DEBUG is False, send an error message to the admins (unless it's
        # a 404, in which case we check the setting).
        send_broken_links = getattr(settings, 'SEND_BROKEN_LINK_EMAILS', False)

        if not response_code == 404 or send_broken_links:
            log = logging.getLogger('django.request.tastypie')
            log.error('Internal Server Error: %s' % request.path, exc_info=True,
                      extra={'status_code': response_code, 'request': request})

        # Send the signal so other apps are aware of the exception.
        got_request_exception.send(self.__class__, request=request)

        # Prep the data going out.
        data = {
            "error_message": getattr(
                settings, 
                'TASTYPIE_CANNED_ERROR', 
                "Sorry, this request could not be processed. Please try again later."),
        }
        return self.build_error_response(request, data, response_class=response_class)
Пример #40
0
    def test_signal_integration(self):
        try:
            int('hello')
        except:
            got_request_exception.send(sender=self.__class__, request=None)
        else:
            self.fail('Expected an exception.')

        self.assertEquals(len(self.raven.events), 1)
        event = self.raven.events.pop(0)
        assert 'exception' in event
        exc = event['exception']['values'][0]
        self.assertEquals(exc['type'], 'ValueError')
        self.assertEquals(exc['value'],
                          "invalid literal for int() with base 10: 'hello'")
        self.assertEquals(event['level'], logging.ERROR)
        self.assertEquals(
            event['message'],
            "ValueError: invalid literal for int() with base 10: 'hello'")
        self.assertEquals(event['culprit'],
                          'tests.tests in test_signal_integration')
    def test_signal_integration(self):
        with Settings(HEKA_CONF=self.HEKA_CONF,
                      HEKA=self.HEKA,
                      SENTRY_CLIENT=self.SENTRY_CLIENT,
                      SENTRY_DSN=DSN):

            self.raven = get_client()

            try:
                int('hello')
            except:
                got_request_exception.send(sender=self.__class__, request=None)
            else:
                self.fail('Expected an exception.')

            msgs = []
            for mdata in settings.HEKA.stream.msgs:
                h, m = decode_message(mdata)
                msgs.append(m)

            self.assertEquals(len(msgs), 1)

            event = self.raven.decode(msgs[0].payload)
            self.assertTrue('sentry.interfaces.Exception' in event)
            exc = event['sentry.interfaces.Exception']
            self.assertEquals(exc['type'], 'ValueError')
            self.assertEquals(
                exc['value'],
                u"invalid literal for int() with base 10: 'hello'")
            self.assertEquals(event['level'], logging.ERROR)
            self.assertEquals(
                event['message'],
                u"ValueError: invalid literal for int() with base 10: 'hello'")
            self.assertEquals(
                event['culprit'],
                'tests.contrib.django.tests in test_signal_integration')

            # The project_id must be extracted from the SENTRY_DSN
            # option
            self.assertEquals(event['project'], str(TESTING_PROJECT_ID))
Пример #42
0
    def test_signal_integration(self):
        try:
            int('hello')
        except:
            got_request_exception.send(sender=self.__class__, request=None)
        else:
            self.fail('Expected an exception.')

        events = [self.raven.decode(json.loads(msg)['payload'])
                  for msg in settings.METLOG.sender.msgs]

        eq_(len(events), 1)
        event = events.pop(0)
        self.assertTrue('sentry.interfaces.Exception' in event)
        exc = event['sentry.interfaces.Exception']
        eq_(exc['type'], 'ValueError')
        eq_(exc['value'], u"invalid literal for int() with base 10: 'hello'")
        eq_(event['level'], logging.ERROR)
        eq_(event['message'],
            u"ValueError: invalid literal for int() with base 10: 'hello'")
        eq_(event['culprit'],
            'solitude.tests.test_metlog.test_signal_integration')
Пример #43
0
        def _wrapped(request, *a, **kw):
            try:
                status = 200
                headers = {}
                ret = f(request, *a, **kw)

                if isinstance(ret, tuple):
                    if len(ret) == 3:
                        ret, status, headers = ret
                    else:
                        ret, status = ret

                # Some errors are not exceptions. :\
                if isinstance(ret, http.HttpResponseNotAllowed):
                    blob = _dump_json({
                        'error': 405,
                        'message': 'HTTP method not allowed.'
                    })
                    return http.HttpResponse(blob,
                                             status=405,
                                             content_type=JSON)

                # Allow HttpResponses to go straight through.
                if isinstance(ret, http.HttpResponse):
                    return ret

                blob = _dump_json(ret)
                response = http.HttpResponse(blob,
                                             status=status,
                                             content_type=content_type)
                for k in headers:
                    response[k] = headers[k]
                return response
            except http.Http404 as e:
                blob = _dump_json({
                    'error': 404,
                    'message': six.text_type(e),
                })
                logger.warning('Not found: %s',
                               request.path,
                               extra={
                                   'status_code': 404,
                                   'request': request,
                               })
                return http.HttpResponseNotFound(blob, content_type=JSON)
            except PermissionDenied as e:
                logger.warning('Forbidden (Permission denied): %s',
                               request.path,
                               extra={
                                   'status_code': 403,
                                   'request': request,
                               })
                blob = _dump_json({
                    'error': 403,
                    'message': six.text_type(e),
                })
                return http.HttpResponseForbidden(blob, content_type=JSON)
            except BadRequest as e:
                blob = _dump_json({
                    'error': 400,
                    'message': six.text_type(e),
                })
                return http.HttpResponseBadRequest(blob, content_type=JSON)
            except Exception as e:
                exc_data = {
                    'error': 500,
                    'message': 'An error occurred',
                }
                if settings.DEBUG:
                    exc_data['message'] = six.text_type(e)
                    exc_data['traceback'] = traceback.format_exc()

                blob = _dump_json(exc_data)

                # Generate the usual 500 error email with stack trace and full
                # debugging information
                logger.error('Internal Server Error: %s',
                             request.path,
                             exc_info=True,
                             extra={
                                 'status_code': 500,
                                 'request': request
                             })

                # Here we lie a little bit. Because we swallow the exception,
                # the BaseHandler doesn't get to send this signal. It sets the
                # sender argument to self.__class__, in case the BaseHandler
                # is subclassed.
                got_request_exception.send(sender=BaseHandler,
                                           request=request,
                                           exception=e,
                                           exc_data=exc_data)
                return http.HttpResponseServerError(blob, content_type=JSON)
Пример #44
0
 def testSignalsWithoutRequest(self):
     try:
         Message.objects.get(id=999999999)
     except Message.DoesNotExist, exc:
         got_request_exception.send(sender=self.__class__, request=None)
Пример #45
0
        def _wrapped(request, *a, **kw):
            try:
                status = 200
                headers = {}
                ret = f(request, *a, **kw)

                if isinstance(ret, tuple):
                    if len(ret) == 3:
                        ret, status, headers = ret
                    else:
                        ret, status = ret

                # Some errors are not exceptions. :\
                if isinstance(ret, http.HttpResponseNotAllowed):
                    blob = _dump_json({
                        'error': 405,
                        'message': 'HTTP method not allowed.'
                    })
                    return http.HttpResponse(
                        blob, status=405, content_type=JSON)

                # Allow HttpResponses to go straight through.
                if isinstance(ret, http.HttpResponse):
                    return ret

                blob = _dump_json(ret)
                response = http.HttpResponse(blob, status=status,
                                             content_type=content_type)
                for k in headers:
                    response[k] = headers[k]
                return response
            except http.Http404 as e:
                blob = _dump_json({
                    'error': 404,
                    'message': unicode(e),
                })
                logger.warning('Not found: %s', request.path,
                               extra={
                                   'status_code': 404,
                                   'request': request,
                               })
                return http.HttpResponseNotFound(blob, content_type=JSON)
            except PermissionDenied as e:
                logger.warning(
                    'Forbidden (Permission denied): %s', request.path,
                    extra={
                        'status_code': 403,
                        'request': request,
                    })
                blob = _dump_json({
                    'error': 403,
                    'message': unicode(e),
                })
                return http.HttpResponseForbidden(blob, content_type=JSON)
            except BadRequest as e:
                blob = _dump_json({
                    'error': 400,
                    'message': unicode(e),
                })
                return http.HttpResponseBadRequest(blob, content_type=JSON)
            except Exception as e:
                if settings.DEBUG:
                    exc_text = unicode(e)
                else:
                    exc_text = 'An error occurred'
                blob = _dump_json({
                    'error': 500,
                    'message': exc_text,
                })

                # Generate the usual 500 error email with stack trace and full
                # debugging information
                logger.error('Internal Server Error: %s', request.path,
                    exc_info=True,
                    extra={
                        'status_code': 500,
                        'request': request
                    }
                )

                # Here we lie a little bit. Because we swallow the exception,
                # the BaseHandler doesn't get to send this signal. It sets the
                # sender argument to self.__class__, in case the BaseHandler
                # is subclassed.
                got_request_exception.send(sender=BaseHandler, request=request)
                return http.HttpResponseServerError(blob, content_type=JSON)
 def process_exception(self, request, exception):
     got_request_exception.send(sender=self, request=request)
     exc_info = sys.exc_info()
     self.log_exception(request, exception, exc_info)
     return HttpResponseServerError(json.dumps({"code": 1000}),
                                    content_type='application/json')
Пример #47
0
        def _wrapped(request, *args, **kwargs):
            try:
                ret = f(request, *args, **kwargs)

                # Some errors are not exceptions
                if isinstance(ret, http.HttpResponseNotAllowed):
                    return http.HttpResponse(json_dumps(
                        _make_error(_('HTTP method not allowed.'))),
                                             status=405,
                                             content_type=JSON)

                if isinstance(ret, http.HttpResponseBadRequest):
                    return http.HttpResponse(json_dumps(
                        _make_error(_('Bad Request'))),
                                             status=400,
                                             content_type=JSON)

                # Allow other HttpResponses through
                if isinstance(ret, http.HttpResponse):
                    return ret

                # Functions without return values default to a dict which just contains {success: true}
                if ret is None:
                    ret = {}
                if include_success and 'success' not in ret:
                    ret['success'] = True

                content = json_dumps(ret)
                return http.HttpResponse(content,
                                         status=200,
                                         content_type=JSON)

            except http.Http404 as e:
                logger.warning('Not found: %s',
                               request.path,
                               extra={
                                   'status_code': 404,
                                   'request': request,
                               })
                return http.HttpResponseNotFound(json_dumps(_make_error(
                    str(e))),
                                                 content_type=JSON)

            except PermissionDenied as e:
                logger.warning('Forbidden (Permission denied): %s',
                               request.path,
                               extra={
                                   'status_code': 403,
                                   'request': request,
                               })
                return http.HttpResponseForbidden(json_dumps(
                    _make_error(str(e))),
                                                  content_type=JSON)
            except BadRequest as e:
                return http.HttpResponseBadRequest(json_dumps(
                    _make_error(str(e))),
                                                   content_type=JSON)
            except ValidationError as e:
                # Validation errors are raised for errors such as invalid file names.
                # We return HTTP 400s in these cases, and send back a comma separated string of errors.
                # (although generally there will only be one error)
                return http.HttpResponseBadRequest(json_dumps(
                    _make_error(", ".join(e.messages))),
                                                   content_type=JSON)
            except Exception as e:
                data = _make_error(_('An error has occurred'))
                if settings.DEBUG or isinstance(e, InternalServerError):
                    data['error'] = str(e)
                if settings.DEBUG:
                    data['traceback'] = traceback.format_exc()
                content = json_dumps(data)

                # Generate the usual 500 error email with stack trace and full
                # debugging information
                logger.error('Internal Server Error: %s',
                             request.path,
                             exc_info=True,
                             extra={
                                 'status_code': 500,
                                 'request': request
                             })

                # Here we lie a little bit. Because we swallow the exception,
                # the BaseHandler doesn't get to send this signal. It sets the
                # sender argument to self.__class__, in case the BaseHandler
                # is subclassed.
                got_request_exception.send(sender=BaseHandler, request=request)
                return http.HttpResponseServerError(content, content_type=JSON)
Пример #48
0
        def _wrapped(request, *args, **kwargs):
            try:
                ret = f(request, *args, **kwargs)

                # Some errors are not exceptions
                if isinstance(ret, http.HttpResponseNotAllowed):
                    return http.HttpResponse(json_dumps(_make_error(_('HTTP method not allowed.'))), status=405, content_type=JSON)

                if isinstance(ret, http.HttpResponseBadRequest):
                    return http.HttpResponse(json_dumps(_make_error(_('Bad Request'))), status=400, content_type=JSON)

                # Allow other HttpResponses through
                if isinstance(ret, http.HttpResponse):
                    return ret

                # Functions without return values default to a dict which just contains {success: true}
                if ret is None:
                    ret = {}
                if include_success and 'success' not in ret:
                    ret['success'] = True

                content = json_dumps(ret)
                return http.HttpResponse(content, status=200, content_type=JSON)

            except http.Http404 as e:
                logger.warning('Not found: %s', request.path,
                               extra={
                                   'status_code': 404,
                                   'request': request,
                               })
                return http.HttpResponseNotFound(json_dumps(_make_error(str(e))), content_type=JSON)

            except PermissionDenied as e:
                logger.warning(
                    'Forbidden (Permission denied): %s', request.path,
                    extra={
                        'status_code': 403,
                        'request': request,
                    })
                return http.HttpResponseForbidden(json_dumps(_make_error(str(e))), content_type=JSON)
            except BadRequest as e:
                return http.HttpResponseBadRequest(json_dumps(_make_error(str(e))), content_type=JSON)
            except ValidationError as e:
                # Validation errors are raised for errors such as invalid file names.
                # We return HTTP 400s in these cases, and send back a comma separated string of errors.
                # (although generally there will only be one error)
                return http.HttpResponseBadRequest(json_dumps(_make_error(", ".join(e.messages))), content_type=JSON)
            except Exception as e:
                data = _make_error(_('An error has occurred'))
                if settings.DEBUG or isinstance(e, InternalServerError):
                    data['error'] = str(e)
                if settings.DEBUG:
                    data['traceback'] = traceback.format_exc()
                content = json_dumps(data)

                # Generate the usual 500 error email with stack trace and full
                # debugging information
                logger.error(
                    'Internal Server Error: %s', request.path,
                    exc_info=True,
                    extra={
                        'status_code': 500,
                        'request': request
                    }
                )

                # Here we lie a little bit. Because we swallow the exception,
                # the BaseHandler doesn't get to send this signal. It sets the
                # sender argument to self.__class__, in case the BaseHandler
                # is subclassed.
                got_request_exception.send(sender=BaseHandler, request=request)
                return http.HttpResponseServerError(content, content_type=JSON)
Пример #49
0
 def dispatch(self, request, *args, **kwargs):
     try:
         return super().dispatch(request, *args, **kwargs)
     except Exception as e:
         got_request_exception.send(sender=self, request=request)
         return self.respond({"error": str(e)}, status=500)
Пример #50
0
def custom_exception_handler(exc, context=None):
    """
    Custom exception handler for DRF, which ensures every exception we throw
    is caught, returned as a nice DRF Response, while still going to sentry
    etc.

    This is mostly copied from DRF exception handler, with the following
    changes/additions:
    - A condition preventing set_rollback() from being called in some cases
      where we know there might be something to record in the database
    - Handling of non-API exceptions, returning an 500 error that looks like an
      API response, while still logging things to Sentry.
    """
    # If propagate is true, bail early.
    if settings.DEBUG_PROPAGATE_EXCEPTIONS:
        raise

    if isinstance(exc, Http404):
        exc = exceptions.NotFound()
    elif isinstance(exc, PermissionDenied):
        exc = exceptions.PermissionDenied()

    if isinstance(exc, exceptions.APIException):
        headers = {}
        if getattr(exc, 'auth_header', None):
            headers['WWW-Authenticate'] = exc.auth_header
        if getattr(exc, 'wait', None):
            headers['Retry-After'] = '%d' % exc.wait

        if isinstance(exc.detail, (list, dict)):
            data = exc.detail
            code_or_codes = exc.get_codes()
        else:
            data = {'detail': exc.detail}
            code_or_codes = exc.get_codes()

        # If it's not a throttled/permission denied coming from a restriction,
        # we can roll the current transaction back. Otherwise don't, we may
        # need to record something in the database.
        # Note: `code_or_codes` can be a string, or a list of strings, or even
        # a dict of strings here, depending on what happened. Fortunately the
        # only thing we care about is the most basic case, a string, we don't
        # need to test for the rest.
        if not isinstance(exc, exceptions.Throttled) and not (
                isinstance(exc, exceptions.PermissionDenied)
                and code_or_codes == 'permission_denied_restriction'):
            set_rollback()
        if isinstance(exc, UnavailableForLegalReasons):
            url = 'https://www.mozilla.org/about/policy/transparency/'
            headers['Link'] = f'<{url}>; rel="blocked-by"'
        return Response(data, status=exc.status_code, headers=headers)
    else:
        # Not a DRF exception, we want to return an APIfied 500 error while
        # still logging it to Sentry.
        data = base_500_data()

        # Send the got_request_exception signal so other apps like sentry
        # are aware of the exception. The sender does not match what a real
        # exception would do (we don't have access to the handler here) but it
        # should not be an issue, what matters is the request.
        request = context.get('request')
        sender = context.get('view').__class__
        got_request_exception.send(sender, request=request)

        # Send the 500 response back.
        response = Response(data, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    return response
Пример #51
0
 def process_exception(self, request, exception):
     if isinstance(exception, RecordModifiedError):
         got_request_exception.send(sender=self, request=request)
         callback = get_callable(handler409)
         return callback(request, target=exception.target)
Пример #52
0
 def testSignalsWithoutRequest(self):
     try:
         Message.objects.get(id=999999999)
     except Message.DoesNotExist, exc:
         got_request_exception.send(sender=self.__class__, request=None)
Пример #53
0
        def _wrapped(request, *a, **kw):
            try:
                status = 200
                headers = {}
                ret = f(request, *a, **kw)

                if isinstance(ret, tuple):
                    if len(ret) == 3:
                        ret, status, headers = ret
                    else:
                        ret, status = ret

                if isinstance(ret, http.HttpResponseNotAllowed):
                    blob = _dump_json({
                        'error': 405,
                        'message': 'HTTP method not allowed.'
                    })
                    return http.HttpResponse(blob,
                                             status=405,
                                             content_type=JSON)

                if isinstance(ret, http.HttpResponse):
                    return ret

                blob = _dump_json(ret)
                response = http.HttpResponse(blob,
                                             status=status,
                                             content_type=content_type)
                for k in headers:
                    response[k] = headers[k]
                return response

            except http.Http404 as e:
                blob = _dump_json({
                    'error': 404,
                    'message': str(e),
                })
                logger.warning('Not found: %s',
                               request.path,
                               extra={
                                   'status_code': 404,
                                   'request': request,
                               })
                return http.HttpResponseNotFound(blob, content_type=JSON)

            except BadRequest as e:
                blob = _dump_json({
                    'error': 400,
                    'message': str(e),
                })
                return http.HttpResponseBadRequest(blob, content_type=JSON)

            except Exception as e:
                exc_data = {
                    'error': 500,
                    'message': 'An error occurred',
                }
                if settings.DEBUG:
                    exc_data['message'] = str(e)
                    exc_data['traceback'] = traceback_prettify(
                        traceback.format_exc())[8:]

                blob = _dump_json(exc_data)

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

                got_request_exception.send(sender=BaseHandler,
                                           request=request,
                                           exception=e,
                                           exc_data=exc_data)
                return http.HttpResponseServerError(blob, content_type=JSON)
Пример #54
0
    def error_handler(self, e, request, meth):
        """
        Override this method to add handling of errors customized for your 
        needs
        """
        debug_msg = None

        if request.REQUEST.get('debug') or settings.DEBUG:
            if isinstance(e, api_errors.APIException) and e.debug:
                debug_msg = e.debug
            else:    
                exc_type, exc_value, tb = sys.exc_info()
                debug_msg = '%s\n' % ''.join(traceback.format_exception(exc_type, exc_value, tb, 20))
            print debug_msg
                
        if isinstance(e, TypeError):
            result = rc.ALL_OK
            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)
            error_dict = {
                'code': api_errors.ERROR_GENERAL_BAD_SIGNATURE,
                'message': msg
            }
            if request.REQUEST.get('debug') or settings.DEBUG:
                error_dict['debug'] = debug_msg
            result.content = {
                'success': False,
                'error': error_dict
            }
            return result
        
        elif isinstance(e, Http404):
            return make_error_response(api_errors.ERROR_GENERAL_NOT_FOUND)
 
        elif isinstance(e, api_errors.APIException):
            return make_error_response(e.code, debug_msg)
            
        elif isinstance(e, User.DoesNotExist):
            return make_error_response(api_errors.ERROR_GENERAL_USER_NOT_FOUND, debug_msg)

        elif isinstance(e, InvalidId):
            return make_error_response(api_errors.ERROR_GENERAL_BAD_ID_FORMAT, debug_msg)
        
        elif isinstance(e, ObjectDoesNotExist):
            return make_error_response(api_errors.ERROR_GENERAL_TARGET_NOT_FOUND, debug_msg)
        
        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.
            """
            # report the error to django
            got_request_exception.send(sender=self, request=request)
            
            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 make_error_response(api_errors.ERROR_GENERAL_UNKNOWN_ERROR, debug_msg)
                # return HttpResponseServerError(
                #     format_error('\n'.join(rep.format_exception())))
            else:
                return make_error_response(api_errors.ERROR_GENERAL_UNKNOWN_ERROR)
Пример #55
0
 def process_exception(self, request, exception):
     # Make sure the exception signal is fired for Sentry
     got_request_exception.send(sender=self, request=request)
     return HttpResponse('foo')
Пример #56
0
    def _wrapped(request, *a, **kw):
        try:
            status = 200
            headers = {}
            ret = f(request, *a, **kw)

            if isinstance(ret, tuple):
                if len(ret) == 3:
                    ret, status, headers = ret
                else:
                    ret, status = ret

            # Some errors are not exceptions. :\
            if isinstance(ret, http.HttpResponseNotAllowed):
                blob = json.dumps({
                    'error': 405,
                    'message': 'HTTP method not allowed.'
                })
                return http.HttpResponse(blob, status=405, content_type=JSON)

            if isinstance(ret, (str, unicode)):
                blob = ret
            else:
                blob = json.dumps(ret)

            response = http.HttpResponse(blob, status=status,
                                         content_type=JSON)
            for k in headers:
                response[k] = headers[k]
            return response
        except http.Http404 as e:
            blob = json.dumps({
                'error': 404,
                'message': unicode(e),
            })
            logger.warning('Not found: %s', request.path,
                           extra={
                               'status_code': 404,
                               'request': request,
                           })
            return http.HttpResponseNotFound(blob, content_type=JSON)
        except PermissionDenied as e:
            logger.warning('Forbidden (Permission denied): %s', request.path,
                           extra={
                               'status_code': 403,
                               'request': request,
                           })
            blob = json.dumps({
                'error': 403,
                'message': unicode(e),
            })
            return http.HttpResponseForbidden(blob, content_type=JSON)
        except BadRequest as e:
            blob = json.dumps({
                'error': 400,
                'message': unicode(e),
            })
            return http.HttpResponseBadRequest(blob, content_type=JSON)
        except Exception as e:
            blob = json.dumps({
                'error': 500,
                'message': unicode(e),
            })
            logger.exception(unicode(e))

            # Here we lie a little bit. Because we swallow the exception, the
            # BaseHandler doesn't get to send this signal. It sets the sender
            # argument to self.__class__, in case the BaseHandler is
            # subclassed.
            got_request_exception.send(sender=BaseHandler, request=request)
            return http.HttpResponseServerError(blob, content_type=JSON)
Пример #57
0
    def _wrapped(request, *a, **kw):
        try:
            status = 200
            headers = {}
            ret = f(request, *a, **kw)

            if isinstance(ret, tuple):
                if len(ret) == 3:
                    ret, status, headers = ret
                else:
                    ret, status = ret

            # Some errors are not exceptions. :\
            if isinstance(ret, http.HttpResponseNotAllowed):
                blob = json.dumps({
                    'error': 405,
                    'message': 'HTTP method not allowed.'
                })
                return http.HttpResponse(blob, status=405, content_type=JSON)

            if isinstance(ret, (str, unicode)):
                blob = ret
            else:
                blob = json.dumps(ret)

            response = http.HttpResponse(blob,
                                         status=status,
                                         content_type=JSON)
            for k in headers:
                response[k] = headers[k]
            return response
        except http.Http404 as e:
            blob = json.dumps({
                'error': 404,
                'message': unicode(e),
            })
            logger.warning('Not found: %s',
                           request.path,
                           extra={
                               'status_code': 404,
                               'request': request,
                           })
            return http.HttpResponseNotFound(blob, content_type=JSON)
        except PermissionDenied as e:
            logger.warning('Forbidden (Permission denied): %s',
                           request.path,
                           extra={
                               'status_code': 403,
                               'request': request,
                           })
            blob = json.dumps({
                'error': 403,
                'message': unicode(e),
            })
            return http.HttpResponseForbidden(blob, content_type=JSON)
        except BadRequest as e:
            blob = json.dumps({
                'error': 400,
                'message': unicode(e),
            })
            return http.HttpResponseBadRequest(blob, content_type=JSON)
        except Exception as e:
            blob = json.dumps({
                'error': 500,
                'message': unicode(e),
            })
            logger.exception(unicode(e))

            # Here we lie a little bit. Because we swallow the exception, the
            # BaseHandler doesn't get to send this signal. It sets the sender
            # argument to self.__class__, in case the BaseHandler is
            # subclassed.
            got_request_exception.send(sender=BaseHandler, request=request)
            return http.HttpResponseServerError(blob, content_type=JSON)