middleware: Handle page not found errors specially

- Show a different message for them.

Test:

- Try to visit page like /plinth/apps/sharing/foo/edit/ where a share named
'foo' does not exist. The common error handling middleware is triggered and an
alert message 'Page not found' with exception trace back is shown.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: Veiko Aasa <veiko17@disroot.org>
This commit is contained in:
Sunil Mohan Adapa 2024-12-28 14:06:19 -08:00 committed by Veiko Aasa
parent 38829a3cfa
commit 26d317bfd5
No known key found for this signature in database
GPG Key ID: 478539CAE680674E
2 changed files with 23 additions and 4 deletions

View File

@ -11,7 +11,7 @@ from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.core.exceptions import PermissionDenied
from django.db.utils import OperationalError
from django.http import HttpResponseNotAllowed
from django.http import Http404, HttpResponseNotAllowed
from django.shortcuts import redirect, render
from django.template.response import SimpleTemplateResponse
from django.utils.deprecation import MiddlewareMixin
@ -143,12 +143,19 @@ class CommonErrorMiddleware(MiddlewareMixin):
# to infinite redirects.
return None
if request.method == 'POST':
if isinstance(exception, Http404):
message = _('Page not found: {url}').format(url=request.path)
exception = None # Don't show exception details
elif request.method == 'POST':
message = _('Error running operation.')
else:
message = _('Error loading page.')
views.messages_error(request, message, exception)
if exception:
views.messages_error(request, message, exception)
else:
messages.error(request, message)
redirect_url = CommonErrorMiddleware._get_redirect_url_on_error(
request)
return redirect(redirect_url)

View File

@ -9,7 +9,7 @@ import pytest
from django.contrib.auth.models import AnonymousUser, Group, User
from django.core.exceptions import PermissionDenied
from django.db.utils import OperationalError
from django.http import (HttpResponse, HttpResponseNotAllowed,
from django.http import (Http404, HttpResponse, HttpResponseNotAllowed,
HttpResponseRedirect)
from django.test.client import RequestFactory
from django.urls import resolve
@ -294,6 +294,18 @@ class TestCommonErrorMiddleware:
assert response.template_name == 'error.html'
assert 'message' in response.context_data
@staticmethod
@patch('django.contrib.messages.error')
def test_404_error_get(messages_error, middleware, web_request, test_menu):
"""Test that 404 page not found errors are handled."""
response = middleware.process_exception(web_request, Http404())
assert isinstance(response, HttpResponseRedirect)
assert response.url == '/apps/'
messages_error.assert_called_once()
assert messages_error.call_args.args[0] == web_request
assert messages_error.call_args.args[1].startswith(
'Page not found: /apps/testapp/')
@staticmethod
@patch('django.contrib.messages.error')
def test_other_error_get(messages_error, middleware, web_request,