In our project, we have used django SessionMiddleware
to handle users sessions and it's working fine. The only problem here is when PermissionDenied
exceptions happens, an error and its traceback will be printed out in the console! However as expected, by raising that exception, the 403 page will show to the user, but I think it doesn't seem rational, because the middleware here is handling the exception! Just like not found exception, I expect no error in the console. Is there anything wrong?!
here is the middleware settings:
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django_otp.middleware.OTPMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'axes.middleware.AxesMiddleware',
]
And here's the printed error:
Forbidden (Permission denied): /the/not_allowed/page
Traceback (most recent call last):
File "/venv/lib/python3.8/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/venv/lib/python3.8/site-packages/django/core/handlers/base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/venv/lib/python3.8/site-packages/django/core/handlers/base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/lib/python3.8/contextlib.py", line 75, in inner
return func(*args, **kwds)
File "/our_project/base/decorators.py", line 88, in wrapper
return view_func(request, *args, **kwargs)
File "/venv/lib/python3.8/site-packages/django/contrib/auth/decorators.py", line 21, in _wrapped_view
return view_func(request, *args, **kwargs)
File "/venv/lib/python3.8/site-packages/django/contrib/auth/decorators.py", line 20, in _wrapped_view
if test_func(request.user):
File "/venv/lib/python3.8/site-packages/django/contrib/auth/decorators.py", line 70, in check_perms
raise PermissionDenied
django.core.exceptions.PermissionDenied
From this comment
In this example the exception is raised from
permission_required
decorator indjango.contrib.auth.decorators
. I passedraise_exception=True
to this decorator to make it raise exception instead of redirecting to login page
So, it is clear that you have set raise_exception=True
in your decorator.
and from the doc
If the
raise_exception
parameter is given, the decorator will raisePermissionDenied
, prompting the 403 (HTTP Forbidden) view instead of redirecting to the login page.
So, technically, when the conditions are not met, Django will raise an exception. But, depending on the value of 403.html
, Django will show you either the plain 403 page or custom HTML response.
I expect no error in the console. Is there anything wrong?
There is nothing wrong here (or I couldn't see anything).
So, if you want to omit the traceback from the console, you may need to write a error handling middleware to handle this exception.
# error handling middleware
from django.core.exceptions import PermissionDenied
from django.shortcuts import render
class PermissionDeniedErrorHandler:
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):
# This is the method that responsible for the safe-exception handling
if isinstance(exception, PermissionDenied):
return render(
request=request,
template_name="your_custom_403.html",
status=403
)
return None
Note: Do not forgot to bind this middleware in your MIDDLEWARE
settings.
and thus, you will not get any error tracebacks in the console.
Cheers!!!