Django except error

The web framework for perfectionists with deadlines.

Django Exceptions¶

Django raises some of its own exceptions as well as standard Python exceptions.

Django Core Exceptions¶

Django core exception classes are defined in django.core.exceptions.

AppRegistryNotReady

exception AppRegistryNotReady[source]

This exception is raised when attempting to use models before the app
loading process
, which initializes the ORM, is
complete.

EmptyResultSet

exception EmptyResultSet[source]

EmptyResultSet may be raised during query generation if a query won’t
return any results. Most Django projects won’t encounter this exception,
but it might be useful for implementing custom lookups and expressions.

FieldDoesNotExist

exception FieldDoesNotExist[source]

The FieldDoesNotExist exception is raised by a model’s
_meta.get_field() method when the requested field does not exist on the
model or on the model’s parents.

SuspiciousOperation

exception SuspiciousOperation[source]

The SuspiciousOperation exception is raised when a user has
performed an operation that should be considered suspicious from a security
perspective, such as tampering with a session cookie. Subclasses of
SuspiciousOperation include:

  • DisallowedHost
  • DisallowedModelAdminLookup
  • DisallowedModelAdminToField
  • DisallowedRedirect
  • InvalidSessionKey
  • RequestDataTooBig
  • SuspiciousFileOperation
  • SuspiciousMultipartForm
  • SuspiciousSession
  • TooManyFieldsSent

If a SuspiciousOperation exception reaches the ASGI/WSGI handler level
it is logged at the Error level and results in
a HttpResponseBadRequest. See the logging
documentation
for more information.

PermissionDenied

exception PermissionDenied[source]

The PermissionDenied exception is raised when a user does not have
permission to perform the action requested.

ViewDoesNotExist

exception ViewDoesNotExist[source]

The ViewDoesNotExist exception is raised by
django.urls when a requested view does not exist.

MiddlewareNotUsed

exception MiddlewareNotUsed[source]

The MiddlewareNotUsed exception is raised when a middleware is not
used in the server configuration.

ImproperlyConfigured

exception ImproperlyConfigured[source]

The ImproperlyConfigured exception is raised when Django is
somehow improperly configured – for example, if a value in settings.py
is incorrect or unparseable.

FieldError

exception FieldError[source]

The FieldError exception is raised when there is a problem with a
model field. This can happen for several reasons:

  • A field in a model clashes with a field of the same name from an
    abstract base class
  • An infinite loop is caused by ordering
  • A keyword cannot be parsed from the filter parameters
  • A field cannot be determined from a keyword in the query
    parameters
  • A join is not permitted on the specified field
  • A field name is invalid
  • A query contains invalid order_by arguments

ValidationError

exception ValidationError[source]

The ValidationError exception is raised when data fails form or
model field validation. For more information about validation, see
Form and Field Validation,
Model Field Validation and the
Validator Reference.

NON_FIELD_ERRORS

NON_FIELD_ERRORS

ValidationErrors that don’t belong to a particular field in a form
or model are classified as NON_FIELD_ERRORS. This constant is used
as a key in dictionaries that otherwise map fields to their respective
list of errors.

BadRequest

exception BadRequest[source]

The BadRequest exception is raised when the request cannot be
processed due to a client error. If a BadRequest exception reaches the
ASGI/WSGI handler level it results in a
HttpResponseBadRequest.

RequestAborted

exception RequestAborted[source]

The RequestAborted exception is raised when an HTTP body being read
in by the handler is cut off midstream and the client connection closes,
or when the client does not send data and hits a timeout where the server
closes the connection.

It is internal to the HTTP handler modules and you are unlikely to see
it elsewhere. If you are modifying HTTP handling code, you should raise
this when you encounter an aborted request to make sure the socket is
closed cleanly.

SynchronousOnlyOperation

exception SynchronousOnlyOperation[source]

The SynchronousOnlyOperation exception is raised when code that
is only allowed in synchronous Python code is called from an asynchronous
context (a thread with a running asynchronous event loop). These parts of
Django are generally heavily reliant on thread-safety to function and don’t
work correctly under coroutines sharing the same thread.

If you are trying to call code that is synchronous-only from an
asynchronous thread, then create a synchronous thread and call it in that.
You can accomplish this is with asgiref.sync.sync_to_async().

URL Resolver exceptions¶

URL Resolver exceptions are defined in django.urls.

Resolver404

exception Resolver404

The Resolver404 exception is raised by
resolve() if the path passed to resolve() doesn’t
map to a view. It’s a subclass of django.http.Http404.

NoReverseMatch

exception NoReverseMatch

The NoReverseMatch exception is raised by django.urls when a
matching URL in your URLconf cannot be identified based on the parameters
supplied.

Database Exceptions¶

Database exceptions may be imported from django.db.

Django wraps the standard database exceptions so that your Django code has a
guaranteed common implementation of these classes.

exception Error[source]
exception InterfaceError[source]
exception DatabaseError[source]
exception DataError[source]
exception OperationalError[source]
exception IntegrityError[source]
exception InternalError[source]
exception ProgrammingError[source]
exception NotSupportedError[source]

The Django wrappers for database exceptions behave exactly the same as
the underlying database exceptions. See PEP 249, the Python Database API
Specification v2.0, for further information.

As per PEP 3134, a __cause__ attribute is set with the original
(underlying) database exception, allowing access to any additional
information provided.

exception models.ProtectedError

Raised to prevent deletion of referenced objects when using
django.db.models.PROTECT. models.ProtectedError is a subclass
of IntegrityError.

exception models.RestrictedError

Raised to prevent deletion of referenced objects when using
django.db.models.RESTRICT. models.RestrictedError is a subclass
of IntegrityError.

HTTP Exceptions¶

HTTP exceptions may be imported from django.http.

UnreadablePostError

exception UnreadablePostError

UnreadablePostError is raised when a user cancels an upload.

Sessions Exceptions¶

Sessions exceptions are defined in django.contrib.sessions.exceptions.

SessionInterrupted

exception SessionInterrupted[source]

SessionInterrupted is raised when a session is destroyed in a
concurrent request. It’s a subclass of
BadRequest.

Transaction Exceptions¶

Transaction exceptions are defined in django.db.transaction.

TransactionManagementError

exception TransactionManagementError[source]

TransactionManagementError is raised for any and all problems
related to database transactions.

Testing Framework Exceptions¶

Exceptions provided by the django.test package.

RedirectCycleError

exception client.RedirectCycleError

RedirectCycleError is raised when the test client detects a
loop or an overly long chain of redirects.

Python Exceptions¶

Django raises built-in Python exceptions when appropriate as well. See the
Python documentation for further information on the Built-in Exceptions.

In this article, we will learn Django exception handling in a very brief and concise manner while covering most of the exceptions and error messages in Django.

Why do we need to handle exceptions?

As a developer, you will encounter various errors either while making the web APIs, templates, or while writing any other piece of code.

Dealing with them is a very time taking process but also is an essential task, and hence this critical skill of exceptions and error handling comes into the picture.

What are Exceptions?

Exceptions in coding are those types of events that lead to undesirable events. These are detected by run-time executives(like consoles and terminals) or by Operating Systems.

They need not necessarily stop the whole program but will lead to undesirable outputs.

For e.g :

Let’s say the client wants to see a particular object from the database. But for some reason, that specific object is not present there.

In this case, the server won’t come to a halt, but the client will get an error since the object is not present in the DB, which is undesirable.

The key difference between Exceptions and Errors

Errors are those events due to which the whole system will come to a halt, and the program will not execute.

Nothing can be done with errors; we can only detect and then make appropriate changes such that they don’t happen.

On the other hand, exceptions are something that the developers can deal with without letting the system come to a halt.

Types of Django Exceptions

Exception Handling

Exception Handling

There are many kinds of exceptions in Django, out of which five are extremely important and are used most frequently.

  • Django Exception classes
  • Django URL Resolver Exceptions
  • Django Database Exceptions
  • Django Http Exceptions
  • Django Transaction Exceptions

We will learn about them in detail.

1) Django Exception classes

ID Exception Description
1 AppRegistryNotReady – It occurs when the Django models are loaded before the Django app itself.
– This exception occurs when you are writing your own scripts and not with default Django app files.
2 ObjectDoesNotExist As the name suggests, occurs when Object does not exist.
3 EmptyResultSet Occurs when a query returns an empty set
4 FieldDoesNotExist This occurs when Field doest not exist in a model.
5 MultipleObjectsReturned This occurs when a query returns more than one result
6 SuspiciousOperation This happens when the client does something suspicious for security reasons
7 PermissionDenied Occurs when the user tries to perform a task which he is not allowed to
8 ViewDoesNotExist Occurs when Views doesnt not exist
9 MiddlewareNotUsed This occurs when particular middleware is not used in the MIDDLEWARE section of settings.py
10 ImproperlyConfigured This occurs when somehow, Django is improperly configured. Usually doesn’t happen when working with default Django Files.
11 FieldError Happens when there is an error in Model field
12 ValidationError Happens when Data validation fails in forms or model forms.
Django Exception classes

2) Django URL Resolver Exceptions

ID Exception Description
1 Resolver404 – Raised by the function resolve(), a part of Django.http.Http404 library.
– The exception occurs when path() does not have a valid View to map.
2 NoReverseMatch This occurs when the user searches a wrong endpoint.
Django URL Resolver Exceptions

3) Django Database Exceptions

ID Exception Description
1 DatabaseError Occurs when DB is not available
2 IntegrityError – This occurs when DB expects a value for a field but doesn’t get it from the user.
– If True, Django will store empty values as NULL in the database. Default is False.
3 DataError Occurs due to data-related issues
Django Database Exceptions

4) Django Http Exceptions

This we have seen many times. These are the HTTP exceptions that we import from django.http library

ID Exception Description
1 UnreadablePostError Occurs when a user cancels an upload.
Django Http Exceptions

5) Django Transaction Exceptions

ID Exception Description
1 TransactionManagementError This is raised for all the problems that occur due to database transactions
Django Transaction Exceptions

Simple Implementation of Exception Handling in the Django app

We will do a simple DoesNotExist exception handling on an application that shows information about a particular item in the server.

The code is a part of the Web Application itemsapp built in the REST API article.

Itemsapp is a simple REST API application that allows clients to

  1. View a list of items present in the server (GET endpoint: hostwebsite/items)
  2. Add a new item into the DB (POST endpoint: hostwebsite/items)
  3. View a particular item (GET endpoint: hostwebsite/item/<id>)
  4. Edit a particular item (PUT endpoint: hostwebsite/item/<id>)
  5. Delete a particular item (DELETE endpoint: hostwebsite/item/<id>)

To learn how to make the complete web application, do checkout Rest API article.

Now we will create a webpage that shows the information about a particular item from the DB

  • Create a ItemModel in models.py to store information about items:
from django.db import models

# Create your models here.

class ItemsModel(models.Model):
    id = models.IntegerField(primary_key = True)
    name = models.CharField(max_length = 80)
    price = models.IntegerField()

    class Meta:
        ordering = ['name']

    def __str__(self):
        return f"{self.name}:{self.price}"
  • As shown above, the URL path in urls.py will be:
path('/item/<int:nm>',Item)

Now just add a few items into the DB through the admin site.

Admin
Admin
  • Now in views.py, the code to show a particular item with an id = nm will be:
def Item(request,nm):
        item = ItemModel.objects.get(id = nm)
        return HttpResponse(item)

Run the server and check for an object not present in DB, say id = 4

You will get an error message

DoesNotExist
DoesNotExist

Now we will use Django Exception Handling to handle this error. Edit the code in views.py as follows:

def Item(request,nm):
        try:
            item = ItemsModel.objects.get(id = nm)
        except ItemsModel.DoesNotExist:
            return HttpResponse('Exception: Data Not Found')
        return HttpResponse(item)

Notice the line “except ItemsModel.DoesNotExist“. This is where Python automatically captures the exception. You can replace the exception with one of the exceptions from the list above, and handle the same with a custom error message.

For that first import

from django.core.exceptions import *

That’s it, now we can go on and add exception we want

def Item(request,nm):
        try:
            item = ItemsModel.objects.get(id = nm)
        except ObjectDoesNotExist:
            print('Data Not Found')
        return HttpResponse(item)

Now run the server and search for id = 4

Exception Handling
Exception Handling

Similarly, we will handle other important and most used exceptions from the django.core.exceptions

Some other important Exceptions

First we will have to import the library

from django.core.exceptions import <error_name>

Lets go through the important exceptions

Field Dos Not Exist

This happens when the model field does not exist

try:
    Model.objects.get(<field> = '<value>')
except FieldDoesNotExist:
    print('The Field is missing')

Multiple Objects Returned

Happens when more than one object in DB has same value for a certain field

try:
    Model.objects.get(<name> = '<value>')
except MultipleObjectsReturned:
    print('More than one object with the same name are present in the Database')

View Does Not Exist

Happens when we call a view through path() in urls.py , but the view does not exist.

try:
    path('item/', <View>)
except ViewDoesNotExist:
    print('The View does not exist in views.py')

Validation Error

Happens when certain information in the form data is not valid

data = form.cleaned_data['name']
if '<field_name>' not in data:
    raise ValidationError('This name does not exist')

Conclusion

That’s it, fellas! I do hope that this article helped increase your knowledge and understanding of Django exceptions. Do refer to the official documentation for more information.

Stay safe !! keep Learning !!

Looking at this code:

try:
   ...  # do something
except:
   raise Exception('XYZ has gone wrong...')

Even with DEBUG=True, I don’t want this raise Exception to give that yellow page, but it does.

I want to handle the exception by redirecting users to an error page or shows the error (give a CSS error message on the top of the page…)

How do I handle that? If I simply raise it, I will get yellow debug page (again, I don’t want certain exceptions to stop the site from functioning by showing the debug page when DEBUG=True).

How do I handle these exceptions in views.py?

Martin Thoma's user avatar

Martin Thoma

118k153 gold badges591 silver badges914 bronze badges

asked Jun 5, 2012 at 1:07

user423455's user avatar

5

You have three options here.

  1. Provide a 404 handler or 500 handler
  2. Catch the exception elsewhere in your code and do appropriate redirection
  3. Provide custom middleware with the process_exception implemented

Middleware Example:

class MyExceptionMiddleware(object):
    def process_exception(self, request, exception):
        if not isinstance(exception, SomeExceptionType):
            return None
        return HttpResponse('some message')

answered Jun 5, 2012 at 1:16

Josh Smeaton's user avatar

Josh SmeatonJosh Smeaton

47.3k24 gold badges129 silver badges164 bronze badges

2

You can raise a 404 error or simply redirect user onto your custom error page with error message

from django.http import Http404
#...
def your_view(request)
    #...
    try:
        #... do something
    except:
        raise Http404
        #or
        return redirect('your-custom-error-view-name', error='error messsage')
  1. Django 404 error
  2. Django redirect

answered Jun 5, 2012 at 1:16

chehov's user avatar

chehovchehov

1636 bronze badges

1

Another suggestion could be to use Django messaging framework to display flash messages, instead of an error page.

from django.contrib import messages
#...
def another_view(request):
    #...
    context = {'foo': 'bar'}
    try:
        #... some stuff here
    except SomeException as e:
        messages.add_message(request, messages.ERROR, e)

    return render(request, 'appname/another_view.html', context)

And then in the view as in Django documentation:

{% if messages %}
<ul class="messages">
    {% for message in messages %}
    <li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
    {% endfor %}
</ul>
{% endif %}

answered Oct 25, 2016 at 8:48

simon's user avatar

simonsimon

5301 gold badge4 silver badges14 bronze badges

If you want to get proper traceback and message as well. Then I will suggest using a custom middleware and add it to the settings.py middleware section at the end.

The following code will process the exception only in production. You may remove the DEBUG condition if you wish.

from django.http import HttpResponse
from django.conf import settings
import traceback


class ErrorHandlerMiddleware:

    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        response = self.get_response(request)
        return response

    def process_exception(self, request, exception):
        if not settings.DEBUG:
            if exception:
                message = "{url}n{error}n{tb}".format(
                    url=request.build_absolute_uri(),
                    error=repr(exception),
                    tb=traceback.format_exc()
                )
                # Do whatever with the message now
            return HttpResponse("Error processing the request.", status=500)

answered Jan 24, 2020 at 12:31

HerculesOfHell's user avatar

Django Exceptions

Django raises some of its own exceptions as well as standard Python exceptions.

Django Core Exceptions

Django core exception classes are defined in django.core.exceptions.

AppRegistryNotReady

exception AppRegistryNotReady[source]

This exception is raised when attempting to use models before the app loading process, which initializes the ORM, is complete.

ObjectDoesNotExist

exception ObjectDoesNotExist[source]

The base class for Model.DoesNotExist exceptions. A try/except for ObjectDoesNotExist will catch DoesNotExist exceptions for all models.

See get().

EmptyResultSet

exception EmptyResultSet[source]

EmptyResultSet may be raised during query generation if a query won’t return any results. Most Django projects won’t encounter this exception, but it might be useful for implementing custom lookups and expressions.

FieldDoesNotExist

exception FieldDoesNotExist[source]

The FieldDoesNotExist exception is raised by a model’s _meta.get_field() method when the requested field does not exist on the model or on the model’s parents.

MultipleObjectsReturned

exception MultipleObjectsReturned[source]

The base class for Model.MultipleObjectsReturned exceptions. A try/except for MultipleObjectsReturned will catch MultipleObjectsReturned exceptions for all models.

See get().

SuspiciousOperation

exception SuspiciousOperation[source]

The SuspiciousOperation exception is raised when a user has performed an operation that should be considered suspicious from a security perspective, such as tampering with a session cookie. Subclasses of SuspiciousOperation include:

  • DisallowedHost
  • DisallowedModelAdminLookup
  • DisallowedModelAdminToField
  • DisallowedRedirect
  • InvalidSessionKey
  • RequestDataTooBig
  • SuspiciousFileOperation
  • SuspiciousMultipartForm
  • SuspiciousSession
  • TooManyFieldsSent

If a SuspiciousOperation exception reaches the ASGI/WSGI handler level it is logged at the Error level and results in a HttpResponseBadRequest. See the logging documentation for more information.

PermissionDenied

exception PermissionDenied[source]

The PermissionDenied exception is raised when a user does not have permission to perform the action requested.

ViewDoesNotExist

exception ViewDoesNotExist[source]

The ViewDoesNotExist exception is raised by django.urls when a requested view does not exist.

MiddlewareNotUsed

exception MiddlewareNotUsed[source]

The MiddlewareNotUsed exception is raised when a middleware is not used in the server configuration.

ImproperlyConfigured

exception ImproperlyConfigured[source]

The ImproperlyConfigured exception is raised when Django is somehow improperly configured – for example, if a value in settings.py is incorrect or unparseable.

FieldError

exception FieldError[source]

The FieldError exception is raised when there is a problem with a model field. This can happen for several reasons:

  • A field in a model clashes with a field of the same name from an abstract base class
  • An infinite loop is caused by ordering
  • A keyword cannot be parsed from the filter parameters
  • A field cannot be determined from a keyword in the query parameters
  • A join is not permitted on the specified field
  • A field name is invalid
  • A query contains invalid order_by arguments

ValidationError

exception ValidationError[source]

The ValidationError exception is raised when data fails form or model field validation. For more information about validation, see Form and Field Validation, Model Field Validation and the Validator Reference.

NON_FIELD_ERRORS

NON_FIELD_ERRORS

ValidationErrors that don’t belong to a particular field in a form or model are classified as NON_FIELD_ERRORS. This constant is used as a key in dictionaries that otherwise map fields to their respective list of errors.

BadRequest

exception BadRequest[source]

The BadRequest exception is raised when the request cannot be processed due to a client error. If a BadRequest exception reaches the ASGI/WSGI handler level it results in a HttpResponseBadRequest.

RequestAborted

exception RequestAborted[source]

The RequestAborted exception is raised when an HTTP body being read in by the handler is cut off midstream and the client connection closes, or when the client does not send data and hits a timeout where the server closes the connection.

It is internal to the HTTP handler modules and you are unlikely to see it elsewhere. If you are modifying HTTP handling code, you should raise this when you encounter an aborted request to make sure the socket is closed cleanly.

SynchronousOnlyOperation

exception SynchronousOnlyOperation[source]

The SynchronousOnlyOperation exception is raised when code that is only allowed in synchronous Python code is called from an asynchronous context (a thread with a running asynchronous event loop). These parts of Django are generally heavily reliant on thread-safety to function and don’t work correctly under coroutines sharing the same thread.

If you are trying to call code that is synchronous-only from an asynchronous thread, then create a synchronous thread and call it in that. You can accomplish this is with asgiref.sync.sync_to_async().

URL Resolver exceptions

URL Resolver exceptions are defined in django.urls.

Resolver404

exception Resolver404

The Resolver404 exception is raised by resolve() if the path passed to resolve() doesn’t map to a view. It’s a subclass of django.http.Http404.

NoReverseMatch

exception NoReverseMatch

The NoReverseMatch exception is raised by django.urls when a matching URL in your URLconf cannot be identified based on the parameters supplied.

Database Exceptions

Database exceptions may be imported from django.db.

Django wraps the standard database exceptions so that your Django code has a guaranteed common implementation of these classes.

exception Error[source]
exception InterfaceError[source]
exception DatabaseError[source]
exception DataError[source]
exception OperationalError[source]
exception IntegrityError[source]
exception InternalError[source]
exception ProgrammingError[source]
exception NotSupportedError[source]

The Django wrappers for database exceptions behave exactly the same as the underlying database exceptions. See PEP 249, the Python Database API Specification v2.0, for further information.

As per PEP 3134, a __cause__ attribute is set with the original (underlying) database exception, allowing access to any additional information provided.

exception models.ProtectedError

Raised to prevent deletion of referenced objects when using django.db.models.PROTECT. models.ProtectedError is a subclass of IntegrityError.

exception models.RestrictedError

Raised to prevent deletion of referenced objects when using django.db.models.RESTRICT. models.RestrictedError is a subclass of IntegrityError.

HTTP Exceptions

HTTP exceptions may be imported from django.http.

UnreadablePostError

exception UnreadablePostError

UnreadablePostError is raised when a user cancels an upload.

Sessions Exceptions

Sessions exceptions are defined in django.contrib.sessions.exceptions.

SessionInterrupted

exception SessionInterrupted[source]

SessionInterrupted is raised when a session is destroyed in a concurrent request. It’s a subclass of BadRequest.

Transaction Exceptions

Transaction exceptions are defined in django.db.transaction.

TransactionManagementError

exception TransactionManagementError[source]

TransactionManagementError is raised for any and all problems related to database transactions.

Testing Framework Exceptions

Exceptions provided by the django.test package.

RedirectCycleError

exception client.RedirectCycleError

RedirectCycleError is raised when the test client detects a loop or an overly long chain of redirects.

Python Exceptions

Django raises built-in Python exceptions when appropriate as well. See the Python documentation for further information on the Built-in Exceptions.


Django

4.1

  • django-admin and manage.py

    django-admin is Django’s command-line utility for administrative tasks.

  • Commands provided by applications

    Some commands are only available when the django.contrib application that implements them has been enabled.

  • The File object

    The django.core.files module and its submodules contain built-in classes for basic handling The File class is thin wrapper around Python object with some

  • File handling

    File handling The object class ContentFile ImageFile Additional methods files attached to objects storage API Getting current FileSystemStorage Uploaded

Until now error messages haven’t been more than mentioned, but if you have tried
out the examples you have probably seen some. There are (at least) two
distinguishable kinds of errors: syntax errors and exceptions.

8.1. Syntax Errors¶

Syntax errors, also known as parsing errors, are perhaps the most common kind of
complaint you get while you are still learning Python:

>>> while True print('Hello world')
  File "<stdin>", line 1
    while True print('Hello world')
                   ^
SyntaxError: invalid syntax

The parser repeats the offending line and displays a little ‘arrow’ pointing at
the earliest point in the line where the error was detected. The error is
caused by (or at least detected at) the token preceding the arrow: in the
example, the error is detected at the function print(), since a colon
(':') is missing before it. File name and line number are printed so you
know where to look in case the input came from a script.

8.2. Exceptions¶

Even if a statement or expression is syntactically correct, it may cause an
error when an attempt is made to execute it. Errors detected during execution
are called exceptions and are not unconditionally fatal: you will soon learn
how to handle them in Python programs. Most exceptions are not handled by
programs, however, and result in error messages as shown here:

>>> 10 * (1/0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero
>>> 4 + spam*3
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'spam' is not defined
>>> '2' + 2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can only concatenate str (not "int") to str

The last line of the error message indicates what happened. Exceptions come in
different types, and the type is printed as part of the message: the types in
the example are ZeroDivisionError, NameError and TypeError.
The string printed as the exception type is the name of the built-in exception
that occurred. This is true for all built-in exceptions, but need not be true
for user-defined exceptions (although it is a useful convention). Standard
exception names are built-in identifiers (not reserved keywords).

The rest of the line provides detail based on the type of exception and what
caused it.

The preceding part of the error message shows the context where the exception
occurred, in the form of a stack traceback. In general it contains a stack
traceback listing source lines; however, it will not display lines read from
standard input.

Built-in Exceptions lists the built-in exceptions and their meanings.

8.3. Handling Exceptions¶

It is possible to write programs that handle selected exceptions. Look at the
following example, which asks the user for input until a valid integer has been
entered, but allows the user to interrupt the program (using Control-C or
whatever the operating system supports); note that a user-generated interruption
is signalled by raising the KeyboardInterrupt exception.

>>> while True:
...     try:
...         x = int(input("Please enter a number: "))
...         break
...     except ValueError:
...         print("Oops!  That was no valid number.  Try again...")
...

The try statement works as follows.

  • First, the try clause (the statement(s) between the try and
    except keywords) is executed.

  • If no exception occurs, the except clause is skipped and execution of the
    try statement is finished.

  • If an exception occurs during execution of the try clause, the rest of the
    clause is skipped. Then, if its type matches the exception named after the
    except keyword, the except clause is executed, and then execution
    continues after the try/except block.

  • If an exception occurs which does not match the exception named in the except
    clause
    , it is passed on to outer try statements; if no handler is
    found, it is an unhandled exception and execution stops with a message as
    shown above.

A try statement may have more than one except clause, to specify
handlers for different exceptions. At most one handler will be executed.
Handlers only handle exceptions that occur in the corresponding try clause,
not in other handlers of the same try statement. An except clause
may name multiple exceptions as a parenthesized tuple, for example:

... except (RuntimeError, TypeError, NameError):
...     pass

A class in an except clause is compatible with an exception if it is
the same class or a base class thereof (but not the other way around — an
except clause listing a derived class is not compatible with a base class).
For example, the following code will print B, C, D in that order:

class B(Exception):
    pass

class C(B):
    pass

class D(C):
    pass

for cls in [B, C, D]:
    try:
        raise cls()
    except D:
        print("D")
    except C:
        print("C")
    except B:
        print("B")

Note that if the except clauses were reversed (with except B first), it
would have printed B, B, B — the first matching except clause is triggered.

All exceptions inherit from BaseException, and so it can be used to serve
as a wildcard. Use this with extreme caution, since it is easy to mask a real
programming error in this way! It can also be used to print an error message and
then re-raise the exception (allowing a caller to handle the exception as well):

import sys

try:
    f = open('myfile.txt')
    s = f.readline()
    i = int(s.strip())
except OSError as err:
    print("OS error: {0}".format(err))
except ValueError:
    print("Could not convert data to an integer.")
except BaseException as err:
    print(f"Unexpected {err=}, {type(err)=}")
    raise

Alternatively the last except clause may omit the exception name(s), however the exception
value must then be retrieved from sys.exc_info()[1].

The tryexcept statement has an optional else
clause
, which, when present, must follow all except clauses. It is useful
for code that must be executed if the try clause does not raise an exception.
For example:

for arg in sys.argv[1:]:
    try:
        f = open(arg, 'r')
    except OSError:
        print('cannot open', arg)
    else:
        print(arg, 'has', len(f.readlines()), 'lines')
        f.close()

The use of the else clause is better than adding additional code to
the try clause because it avoids accidentally catching an exception
that wasn’t raised by the code being protected by the try
except statement.

When an exception occurs, it may have an associated value, also known as the
exception’s argument. The presence and type of the argument depend on the
exception type.

The except clause may specify a variable after the exception name. The
variable is bound to an exception instance with the arguments stored in
instance.args. For convenience, the exception instance defines
__str__() so the arguments can be printed directly without having to
reference .args. One may also instantiate an exception first before
raising it and add any attributes to it as desired.

>>> try:
...     raise Exception('spam', 'eggs')
... except Exception as inst:
...     print(type(inst))    # the exception instance
...     print(inst.args)     # arguments stored in .args
...     print(inst)          # __str__ allows args to be printed directly,
...                          # but may be overridden in exception subclasses
...     x, y = inst.args     # unpack args
...     print('x =', x)
...     print('y =', y)
...
<class 'Exception'>
('spam', 'eggs')
('spam', 'eggs')
x = spam
y = eggs

If an exception has arguments, they are printed as the last part (‘detail’) of
the message for unhandled exceptions.

Exception handlers don’t just handle exceptions if they occur immediately in the
try clause, but also if they occur inside functions that are called (even
indirectly) in the try clause. For example:

>>> def this_fails():
...     x = 1/0
...
>>> try:
...     this_fails()
... except ZeroDivisionError as err:
...     print('Handling run-time error:', err)
...
Handling run-time error: division by zero

8.4. Raising Exceptions¶

The raise statement allows the programmer to force a specified
exception to occur. For example:

>>> raise NameError('HiThere')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: HiThere

The sole argument to raise indicates the exception to be raised.
This must be either an exception instance or an exception class (a class that
derives from Exception). If an exception class is passed, it will
be implicitly instantiated by calling its constructor with no arguments:

raise ValueError  # shorthand for 'raise ValueError()'

If you need to determine whether an exception was raised but don’t intend to
handle it, a simpler form of the raise statement allows you to
re-raise the exception:

>>> try:
...     raise NameError('HiThere')
... except NameError:
...     print('An exception flew by!')
...     raise
...
An exception flew by!
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
NameError: HiThere

8.5. Exception Chaining¶

The raise statement allows an optional from which enables
chaining exceptions. For example:

# exc must be exception instance or None.
raise RuntimeError from exc

This can be useful when you are transforming exceptions. For example:

>>> def func():
...     raise ConnectionError
...
>>> try:
...     func()
... except ConnectionError as exc:
...     raise RuntimeError('Failed to open database') from exc
...
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "<stdin>", line 2, in func
ConnectionError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
RuntimeError: Failed to open database

Exception chaining happens automatically when an exception is raised inside an
except or finally section. This can be
disabled by using from None idiom:

>>> try:
...     open('database.sqlite')
... except OSError:
...     raise RuntimeError from None
...
Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
RuntimeError

For more information about chaining mechanics, see Built-in Exceptions.

8.6. User-defined Exceptions¶

Programs may name their own exceptions by creating a new exception class (see
Classes for more about Python classes). Exceptions should typically
be derived from the Exception class, either directly or indirectly.

Exception classes can be defined which do anything any other class can do, but
are usually kept simple, often only offering a number of attributes that allow
information about the error to be extracted by handlers for the exception.

Most exceptions are defined with names that end in “Error”, similar to the
naming of the standard exceptions.

Many standard modules define their own exceptions to report errors that may
occur in functions they define. More information on classes is presented in
chapter Classes.

8.7. Defining Clean-up Actions¶

The try statement has another optional clause which is intended to
define clean-up actions that must be executed under all circumstances. For
example:

>>> try:
...     raise KeyboardInterrupt
... finally:
...     print('Goodbye, world!')
...
Goodbye, world!
KeyboardInterrupt
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>

If a finally clause is present, the finally
clause will execute as the last task before the try
statement completes. The finally clause runs whether or
not the try statement produces an exception. The following
points discuss more complex cases when an exception occurs:

  • If an exception occurs during execution of the try
    clause, the exception may be handled by an except
    clause. If the exception is not handled by an except
    clause, the exception is re-raised after the finally
    clause has been executed.

  • An exception could occur during execution of an except
    or else clause. Again, the exception is re-raised after
    the finally clause has been executed.

  • If the finally clause executes a break,
    continue or return statement, exceptions are not
    re-raised.

  • If the try statement reaches a break,
    continue or return statement, the
    finally clause will execute just prior to the
    break, continue or return
    statement’s execution.

  • If a finally clause includes a return
    statement, the returned value will be the one from the
    finally clause’s return statement, not the
    value from the try clause’s return
    statement.

For example:

>>> def bool_return():
...     try:
...         return True
...     finally:
...         return False
...
>>> bool_return()
False

A more complicated example:

>>> def divide(x, y):
...     try:
...         result = x / y
...     except ZeroDivisionError:
...         print("division by zero!")
...     else:
...         print("result is", result)
...     finally:
...         print("executing finally clause")
...
>>> divide(2, 1)
result is 2.0
executing finally clause
>>> divide(2, 0)
division by zero!
executing finally clause
>>> divide("2", "1")
executing finally clause
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in divide
TypeError: unsupported operand type(s) for /: 'str' and 'str'

As you can see, the finally clause is executed in any event. The
TypeError raised by dividing two strings is not handled by the
except clause and therefore re-raised after the finally
clause has been executed.

In real world applications, the finally clause is useful for
releasing external resources (such as files or network connections), regardless
of whether the use of the resource was successful.

8.8. Predefined Clean-up Actions¶

Some objects define standard clean-up actions to be undertaken when the object
is no longer needed, regardless of whether or not the operation using the object
succeeded or failed. Look at the following example, which tries to open a file
and print its contents to the screen.

for line in open("myfile.txt"):
    print(line, end="")

The problem with this code is that it leaves the file open for an indeterminate
amount of time after this part of the code has finished executing.
This is not an issue in simple scripts, but can be a problem for larger
applications. The with statement allows objects like files to be
used in a way that ensures they are always cleaned up promptly and correctly.

with open("myfile.txt") as f:
    for line in f:
        print(line, end="")

After the statement is executed, the file f is always closed, even if a
problem was encountered while processing the lines. Objects which, like files,
provide predefined clean-up actions will indicate this in their documentation.

exceptions.py

Exceptions… allow error handling to be organized cleanly in a central or high-level place within the program structure.

— Doug Hellmann, Python Exception Handling Techniques

Exception handling in REST framework views

REST framework’s views handle various exceptions, and deal with returning appropriate error responses.

The handled exceptions are:

  • Subclasses of APIException raised inside REST framework.
  • Django’s Http404 exception.
  • Django’s PermissionDenied exception.

In each case, REST framework will return a response with an appropriate status code and content-type. The body of the response will include any additional details regarding the nature of the error.

Most error responses will include a key detail in the body of the response.

For example, the following request:

DELETE http://api.example.com/foo/bar HTTP/1.1
Accept: application/json

Might receive an error response indicating that the DELETE method is not allowed on that resource:

HTTP/1.1 405 Method Not Allowed
Content-Type: application/json
Content-Length: 42

{"detail": "Method 'DELETE' not allowed."}

Validation errors are handled slightly differently, and will include the field names as the keys in the response. If the validation error was not specific to a particular field then it will use the «non_field_errors» key, or whatever string value has been set for the NON_FIELD_ERRORS_KEY setting.

An example validation error might look like this:

HTTP/1.1 400 Bad Request
Content-Type: application/json
Content-Length: 94

{"amount": ["A valid integer is required."], "description": ["This field may not be blank."]}

Custom exception handling

You can implement custom exception handling by creating a handler function that converts exceptions raised in your API views into response objects. This allows you to control the style of error responses used by your API.

The function must take a pair of arguments, the first is the exception to be handled, and the second is a dictionary containing any extra context such as the view currently being handled. The 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.

For example, you might want to ensure that all error responses include the HTTP status code in the body of the response, like so:

HTTP/1.1 405 Method Not Allowed
Content-Type: application/json
Content-Length: 62

{"status_code": 405, "detail": "Method 'DELETE' not allowed."}

In order to alter the style of the response, you could write the following custom exception handler:

from rest_framework.views import exception_handler

def custom_exception_handler(exc, context):
    # Call REST framework's default exception handler first,
    # to get the standard error response.
    response = exception_handler(exc, context)

    # Now add the HTTP status code to the response.
    if response is not None:
        response.data['status_code'] = response.status_code

    return response

The context argument is not used by the default handler, but can be useful if the exception handler needs further information such as the view currently being handled, which can be accessed as context['view'].

The exception handler must also be configured in your settings, using the EXCEPTION_HANDLER setting key. For example:

REST_FRAMEWORK = {
    'EXCEPTION_HANDLER': 'my_project.my_app.utils.custom_exception_handler'
}

If not specified, the 'EXCEPTION_HANDLER' setting defaults to the standard exception handler provided by REST framework:

REST_FRAMEWORK = {
    'EXCEPTION_HANDLER': 'rest_framework.views.exception_handler'
}

Note that the exception handler will only be called for responses generated by raised exceptions. It will not be used for any responses returned directly by the view, such as the HTTP_400_BAD_REQUEST responses that are returned by the generic views when serializer validation fails.


API Reference

APIException

Signature: APIException()

The base class for all exceptions raised inside an APIView class or @api_view.

To provide a custom exception, subclass APIException and set the .status_code, .default_detail, and default_code attributes on the class.

For example, if your API relies on a third party service that may sometimes be unreachable, you might want to implement an exception for the «503 Service Unavailable» HTTP response code. You could do this like so:

from rest_framework.exceptions import APIException

class ServiceUnavailable(APIException):
    status_code = 503
    default_detail = 'Service temporarily unavailable, try again later.'
    default_code = 'service_unavailable'

Inspecting API exceptions

There are a number of different properties available for inspecting the status
of an API exception. You can use these to build custom exception handling
for your project.

The available attributes and methods are:

  • .detail — Return the textual description of the error.
  • .get_codes() — Return the code identifier of the error.
  • .get_full_details() — Return both the textual description and the code identifier.

In most cases the error detail will be a simple item:

>>> print(exc.detail)
You do not have permission to perform this action.
>>> print(exc.get_codes())
permission_denied
>>> print(exc.get_full_details())
{'message':'You do not have permission to perform this action.','code':'permission_denied'}

In the case of validation errors the error detail will be either a list or
dictionary of items:

>>> print(exc.detail)
{"name":"This field is required.","age":"A valid integer is required."}
>>> print(exc.get_codes())
{"name":"required","age":"invalid"}
>>> print(exc.get_full_details())
{"name":{"message":"This field is required.","code":"required"},"age":{"message":"A valid integer is required.","code":"invalid"}}

ParseError

Signature: ParseError(detail=None, code=None)

Raised if the request contains malformed data when accessing request.data.

By default this exception results in a response with the HTTP status code «400 Bad Request».

AuthenticationFailed

Signature: AuthenticationFailed(detail=None, code=None)

Raised when an incoming request includes incorrect authentication.

By default this exception results in a response with the HTTP status code «401 Unauthenticated», but it may also result in a «403 Forbidden» response, depending on the authentication scheme in use. See the authentication documentation for more details.

NotAuthenticated

Signature: NotAuthenticated(detail=None, code=None)

Raised when an unauthenticated request fails the permission checks.

By default this exception results in a response with the HTTP status code «401 Unauthenticated», but it may also result in a «403 Forbidden» response, depending on the authentication scheme in use. See the authentication documentation for more details.

PermissionDenied

Signature: PermissionDenied(detail=None, code=None)

Raised when an authenticated request fails the permission checks.

By default this exception results in a response with the HTTP status code «403 Forbidden».

NotFound

Signature: NotFound(detail=None, code=None)

Raised when a resource does not exists at the given URL. This exception is equivalent to the standard Http404 Django exception.

By default this exception results in a response with the HTTP status code «404 Not Found».

MethodNotAllowed

Signature: MethodNotAllowed(method, detail=None, code=None)

Raised when an incoming request occurs that does not map to a handler method on the view.

By default this exception results in a response with the HTTP status code «405 Method Not Allowed».

NotAcceptable

Signature: NotAcceptable(detail=None, code=None)

Raised when an incoming request occurs with an Accept header that cannot be satisfied by any of the available renderers.

By default this exception results in a response with the HTTP status code «406 Not Acceptable».

Signature: UnsupportedMediaType(media_type, detail=None, code=None)

Raised if there are no parsers that can handle the content type of the request data when accessing request.data.

By default this exception results in a response with the HTTP status code «415 Unsupported Media Type».

Throttled

Signature: Throttled(wait=None, detail=None, code=None)

Raised when an incoming request fails the throttling checks.

By default this exception results in a response with the HTTP status code «429 Too Many Requests».

ValidationError

Signature: ValidationError(detail, code=None)

The ValidationError exception is slightly different from the other APIException classes:

  • The detail argument is mandatory, not optional.
  • The detail argument may be a list or dictionary of error details, and may also be a nested data structure. By using a dictionary, you can specify field-level errors while performing object-level validation in the validate() method of a serializer. For example. raise serializers.ValidationError({'name': 'Please enter a valid name.'})
  • By convention you should import the serializers module and use a fully qualified ValidationError style, in order to differentiate it from Django’s built-in validation error. For example. raise serializers.ValidationError('This field must be an integer value.')

The ValidationError class should be used for serializer and field validation, and by validator classes. It is also raised when calling serializer.is_valid with the raise_exception keyword argument:

serializer.is_valid(raise_exception=True)

The generic views use the raise_exception=True flag, which means that you can override the style of validation error responses globally in your API. To do so, use a custom exception handler, as described above.

By default this exception results in a response with the HTTP status code «400 Bad Request».


Generic Error Views

Django REST Framework provides two error views suitable for providing generic JSON 500 Server Error and
400 Bad Request responses. (Django’s default error views provide HTML responses, which may not be appropriate for an
API-only application.)

Use these as per Django’s Customizing error views documentation.

rest_framework.exceptions.server_error

Returns a response with status code 500 and application/json content type.

Set as handler500:

handler500 = 'rest_framework.exceptions.server_error'

rest_framework.exceptions.bad_request

Returns a response with status code 400 and application/json content type.

Set as handler400:

handler400 = 'rest_framework.exceptions.bad_request'

Third party packages

The following third-party packages are also available.

DRF Standardized Errors

The drf-standardized-errors package provides an exception handler that generates the same format for all 4xx and 5xx responses. It is a drop-in replacement for the default exception handler and allows customizing the error response format without rewriting the whole exception handler. The standardized error response format is easier to document and easier to handle by API consumers.

Понравилась статья? Поделить с друзьями:
  • Django error logs
  • Django error handlers
  • Django debug false server error 500
  • Django db utils operationalerror near syntax error
  • Django custom error page