Getting rid of Django IOErrors
I'm running a Django site (via Apache/mod_python) and I use Django's facilities to inform me and other developers about internal server errors. Sometimes errors like those appear:
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.p开发者_StackOverflow社区y", 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?)
As far as I found out, those IOError
s are generated by clients that disconnect in the wrong moment and that it's not a problem of my site.
If that is the case: Can I disable the emails for those errors somehow? I really don't want to know about errors that I cannot fix and that aren't really errors.
Extending the solution by @dlowe for Django 1.3, we can write the full working example as:
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,
},
}
}
common/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
You should be able to write a Middleware to catch the exception and you can then "silence" those specific exceptions.
https://docs.djangoproject.com/en/2.2/topics/http/middleware/
In django 1.3 and up, you can use a logging filter class to suppress the exceptions which you aren't interested in. Here's the logging filter class I'm using to narrowly suppress IOError exceptions raised from _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
In Django 1.4, you will be able to do away with most of the complexity and suppress the new exception class UnreadablePostError
. (See this patch).
精彩评论