Как правильно обрабатывать прерванный HTTP-запрос в Django - PullRequest
3 голосов
/ 14 августа 2011

Всякий раз, когда клиент прерывает длительные HTTP-запросы (например, закрывается браузер), кажется, что представления Django вызывают исключение IOError.

Какой правильный способ обнаружить такой прерванный запрос, если я просто хочу игнорироватьих?Просто перехват IOError кажется слишком широким ... может случайно игнорировать другие проблемы с IO.

Ответы [ 4 ]

2 голосов
/ 11 февраля 2012

В django 1.3 и выше вы можете использовать класс logging filter для подавления исключений, которые вас не интересуют. Вот класс фильтра logging, который я использую для узкого подавления исключений IOError, поднятых из _get_raw_post_data()

import sys, traceback
class _SuppressUnreadablePost(object):
    def filter(self, record):
        _, exception, tb = sys.exc_info()
        if isinstance(exception, IOError):
            for _, _, function, _ in traceback.extract_tb(tb):
                if function == '_get_raw_post_data':
                    return False
        return True

В Django 1.4 вы сможете избавиться от большей части сложности и подавить новый класс исключений UnreadablePostError. (См. этот патч ).

1 голос
/ 23 мая 2012

Raven теперь подключается к сигналу got_request_exception () для перехвата необработанных исключений, полностью обходя систему ведения журнала, поэтому решение, предложенное dlowe, больше не работает.

Однако raven ищет атрибут skip_sentry в экземпляре исключения, поэтому вы можете использовать промежуточное ПО для установки его на ошибки, которые вы хотите игнорировать:

import sys
import traceback


class FilterPostErrorsMiddleware(object):
    """
    A middleware that prevents unreadable POST errors to reach Sentry.
    """

    def process_exception(self, request, exception):
        if isinstance(exception, IOError):
            tb = sys.exc_info()[2]
            for _, _, function, _ in traceback.extract_tb(tb):
                if function == '_get_raw_post_data':
                    exception.skip_sentry = True
                    break

Примечание : вам нужно использовать последнюю версию raven (например, 1.8.4), поскольку предыдущие версии по ошибке проверяли атрибут skip_sentry для типа исключения, а не для экземпляра.

1 голос
/ 14 августа 2011

Лучший способ сделать это - использовать пользовательский класс промежуточного программного обеспечения, который реализует process_exception() для возврата настраиваемого HTTP-ответа, скажем, обработанный шаблон errors/request_aborted.html, если пойман IOException .

0 голосов
/ 14 августа 2011

Если вы хотите игнорировать IOError, тогда просто позвольте этому быть.Вам не нужно ловить это.Если вам абсолютно необходимо поймать его, вы можете сделать то, что предложил @Filip Dupanović, и, возможно, вернуть django.http.HttpResponseServerError, чтобы установить код ответа 500.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...