Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.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?)

As far as I found out, those IOErrors 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.

like image 555
Michael Avatar asked Mar 03 '10 23:03

Michael


People also ask

How does Django fix internal server error?

First off check the Apache error log. If there is nothing in Apache error log, due to it being an internal error to your code or Django while handling a request, set DEBUG to True in Django site settings file and restart Apache so details of error display in the browser.

How do I handle exceptions in Django?

Custom exception handlingThe exception handler function should either return a Response object, or return None if the exception cannot be handled. If the handler returns None then the exception will be re-raised and Django will return a standard HTTP 500 'server error' response.

What is Django integrity error?

This means that your DB is expecting that field to have a value. So when it doesn't you get an error. null. If True, Django will store empty values as NULL in the database. Default is False.


3 Answers

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
like image 140
Subhranath Chunder Avatar answered Sep 20 '22 09:09

Subhranath Chunder


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/

like image 41
Brian Luft Avatar answered Sep 20 '22 09:09

Brian Luft


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).

like image 22
dlowe Avatar answered Sep 22 '22 09:09

dlowe