Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django model.DoesNotExist exception somehow replaced with an AttributeError

I'm experiencing an odd exception on a Django 1.5 site:

 "TypeError: 'exceptions.AttributeError' object is not callable"

Essentially it looks like the model.DoesNotExist exception has been replaced with an AttributeError.

The error is intermittent, but once it happens it seems to 'stick' until I restart the process, which makes me think it might be a case of the model class getting incorrectly set in the course of a particular request, and then persisting.

Bottom of traceback:

File "/opt/mysite/django/apps/profiles/models.py", line 353, in profile_from_cache
    profile = self.get(user=user_id)

  File "/opt/mysite/.virtualenvs/django/lib/python2.7/site-packages/django/db/models/manager.py", line 143, in get
    return self.get_query_set().get(*args, **kwargs)

  File "/opt/mysite/.virtualenvs/django/lib/python2.7/site-packages/django/db/models/query.py", line 404, in get
    self.model._meta.object_name)

TypeError: 'exceptions.AttributeError' object is not callable

Line of code from django/db/models/query.py:

if not num:
    raise self.model.DoesNotExist(
        "%s matching query does not exist." %
        self.model._meta.object_name)

So it looks as if it's trying to pass a message to the DoesNotExist exception on the model, but it's somehow been replaced by an AttributeError instead.

The issue only seems to happen from http requests - if I do the same action from the command line I just get a DoesNotExist exception (which is what should be happening).

I can't find any obvious reason this should be happening. Any ideas?

(PS this seems to be the same issue. The user's answer to it, I think, is wrong: https://groups.google.com/forum/#!topic/django-users/k9JMyXlUt3Q)

Possibly relevant code

Here is an outline of the model manager:

class CacheManager(models.Manager):
    def profile_from_cache(self, user_id=None):
        profile = cache.get("profile_%s" % user_id)
        if profile is None:
            try:
                profile = self.get(user=user_id)
            except Profile.DoesNotExist:
                return None
            cache.set("profile_%s" % user_id, profile, settings.CACHE_TIMEOUT)
        return profile

    ...

class Profile(models.Model):
    ...
    caches = CacheManager()

Here's the line of code that seems to be causing the error. In this case it's in some middleware, but there are a few different places, all causing the same thing.

Profile.caches.profile_from_cache(user_id=request.user.pk)
like image 669
seddonym Avatar asked Nov 27 '25 05:11

seddonym


1 Answers

It was because of incorrect syntax elsewhere in the project, that caught multiple exceptions like this:

try:
   do_something()
except AttributeError, Profile.DoesNotExist:
   pass

When it should have been this:

try:
   do_something()
except (AttributeError, Profile.DoesNotExist):
   pass

What was happening was that when this happened, AttributeError got assigned to Profile.DoesNotExist in memory, so when it was raised later, it was the wrong exception.

Thanks to this post for helping.

like image 77
seddonym Avatar answered Nov 28 '25 21:11

seddonym



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!