消除Django的IOErrors

7
我正在运行一个Django网站(通过Apache/mod_python),我使用Django的功能来通知我和其他开发人员有关内部服务器错误的信息。有时会出现这样的错误:
Traceback (most recent call last):

  File "/opt/webapp/externals/lib/django/core/handlers/base.py", line 92, in get_response
    response = callback(request, *callback_args, **callback_kwargs)

  File "/opt/webapp/csite/apps/customers/views.py", line 29, in feedback
    form = FeedbackForm(request.POST)

  File "/opt/webapp/externals/lib/django/core/handlers/modpython.py", line 113, in _get_post
    self._load_post_and_files()

  File "/opt/webapp/externals/lib/django/core/handlers/modpython.py", line 96, in _load_post_and_files
    self._post, self._files = http.QueryDict(self.raw_post_data, encoding=self._encoding), datastructures.MultiValueDict()

  File "/opt/webapp/externals/lib/django/core/handlers/modpython.py", line 163, in _get_raw_post_data
    self._raw_post_data = self._req.read()

IOError: Client read error (Timeout?)

据我所了解,那些IOError是由于客户端在错误的时刻断开连接而产生的,并不是我的网站的问题。
如果是这样的话:我能否以某种方式禁用这些错误的电子邮件通知?我真的不想知道那些我不能修复的不真正是错误的错误。
3个回答

11

参考@dlowe在Django 1.3中的解决方案,我们可以将完整的可工作示例编写为:

settings.py

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'filters': {
        'supress_unreadable_post': {
            '()': 'common.logging.SuppressUnreadablePost',
        }
    },
    'handlers': {
        'mail_admins': {
            'level': 'ERROR',
            'class': 'django.utils.log.AdminEmailHandler',
            'filters': ['supress_unreadable_post'],
        }
    },
    'loggers': {
        'django.request': {
            'handlers': ['mail_admins'],
            'level': 'ERROR',
            'propagate': True,
        },
    }
}

通用/logging.py

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

1
这对我来说不起作用。但是!结果问题是我使用了Sentry和Raven,后者注册了一个处理程序到get_request_exception信号。这个路径跳过了Python日志记录(因此过滤器),直接写入Sentry... - Vajk Hermecz

2
在Django 1.3及以上版本中,您可以使用一个日志过滤器类来抑制您不感兴趣的异常。这是我正在使用的日志过滤器类,它可以狭窄地抑制从_get_raw_post_data()引发的IOError异常:
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。(请参见此补丁)。

2

2
这将适用于在视图函数内发生的IOErrors。对于视图函数外部的IOErrors,您可以怎么做?例如,在向客户端流式传输响应时,例如返回HttpResponse(open('large_text_file.txt'))。 - Eloff
更新此帖子,附上更新的Django文档链接。https://docs.djangoproject.com/en/1.10/topics/http/middleware/#process-exception - lyncas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接