Better Error Messages

Good error messages make for more productive developers. This page is a place to collect error messages that could stand improvement, or which are misleading or confusing in certain contexts. Most of us have had the experience of getting a "weird" message, puzzling it out (perhaps with help from django-users or #django) and then moving on.

Some of these may seem like quick patches but others will take a bit of consideration -- that's why the wiki page rather than individual tickets. Some are more along the lines of "Django Lint" than simple changes to error output.

For now, let's try dividing them into sections by major module. Within those sections suggested format is: error message, explanatory context (often important -- a message that is very helpful in one context can be confusing in another), suggested improvements/changes.

Also see:

django.contrib.auth

If you try to create a model with a table name > 50 characters (and you've enabled django.contrib.auth) then you get a very poor error message when running syncdb.

env src/tmp/qdel$ python ./manage.py syncdb
Creating tables ...
Traceback (most recent call last):
...
...
django.db.utils.DatabaseError: value too long for type character varying(50)

Suggestion: Look for DatabaseError in contrib/auth/management/init.py. Related #18959

django.core

The 404 error page served when django.core.urlresolvers.resolve() fails does not contain the exception stack trace, which makes finding the failing call unnecessarily difficult.

  • Ticket #22055 -- 404 page does not display stack trace when Resolver404 is raised from a view.
  • Ticket #21668 -- Invalid upload_to FileField attribute results in hard-to-debug "Bad Request" 400 error.
  • Ticket #22058 -- Add Http405 exception class and handler405 view (simillar to 404, 403 and 500).

django.core.urlresolver

Better error message when can't import url callback. Related #8809.

django.db

OperationalError: Unable to close due to unfinalised statements

Context: SQLite file permissions are incorrect (directory or DB file lack write permission)
Suggestion: Check file permissions when running with SQLite backend and warn user if they seem incorrect

ProgrammingError: ERROR:  current transaction is aborted, commands ignored until end of transaction block

This pyscopg2 (PostgreSQL) error usually signifies that some previous database query was incorrect (e.g., you tried to order_by() a field that doesn't exist, or put a string in an integer column, etc.). That previous error aborted the transaction, causing all subsequent database access to fail with this message.

If you get this while at a shell, you can fix your database connection by executing a rollback:

from django.db import connection
connection.cursor().execute('rollback')

If you get this from a view, it probably means the immediately previous query had a problem (but was caught by an over-eager exception handler).

In certain situations with PostgreSQL, a bogus error message about SET TIME ZONE may be returned. See #3179 (which is closed, but has a description of the problem). The real error message can probably be found in the postgres log file.

DoesNotExist: %s matching query does not exist

It would be really helpful for the error message to state what the query was, for example:

        raise self.model.DoesNotExist(("%s matching query does not exist " +
            "(query was: %s, %s)") % (self.model._meta.object_name,
                args, kwargs))

If you create a ForeignKey with blank=True, but you don't specify null=True, and try to save the object without a value for the foreign key, you get this exception:

ValueError: Cannot assign None: "Cat.home" does not allow null values.

You could argue that it's obvious, but it's confusing many people:

I think it would be a really good idea to make it really clear from the error message what you need to do (blank=True requires null=True on foreign key fields).

Unfortunately we can't automatically fix it, because if the field is left blank, the developer might be intending to supply the value automatically before save (#13824). A similar issue occurs here: #13776

Here are some tickets that must be paid attention to:

  • Raise explicit error when unpickling QuerySet from incompatible version. #21430
  • Assigning unsaved model to a ForeignKey leads to silent failures. #10811
  • #20752
  • #7074

django.forms

ValidationError: 'Enter a valid date/time in YYYY-MM-DD HH:MM[:ss[.uuuuuu]] format.'

If the error message contained the invalid data, and, especially the name of the field that was being validated, that would be way more helpful.

Integrity Error is raised when trying to edit a model that has some unique_together fields and is registered with list_editable containing some of that fields. Related Ticket #13091.

Ticket #15069 -- ValidationError message isn't helpful in tracking down the field that fails validation.

django.http

AttributeError: Http404 instance has no attribute 'has_header'

Context: Http404 is returned instead of raised
Suggestion: Check type of HttpResponse before attempting to use (perhaps unPythonic?) or possibly give Http404 a clearer name like Http404Exception

django.shortcuts

Invoking .render() with a <coconut> object instead of a HttpRequest as the first argument invokes AttributeError with the message: "'<coconut>' object has no attribute 'META'". Better will be something like, "render() takes a request object for the first argument."

django.template

When resolving a template variable that calls an object method/property. If that method/property has errors we get a VariableDoesNotExist exception without what errors happened, which might confuse the user. See #16383 for more details.

Looking at these might be useful: #6907 and #11421.

Last modified 11 years ago Last modified on Mar 1, 2014, 12:57:14 AM
Note: See TracWiki for help on using the wiki.
Back to Top