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.contrib.auth.decorators import login_required
from django.core.exceptions import PermissionDenied from django.core.exceptions import PermissionDenied
from django.db.utils import OperationalError 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.shortcuts import redirect, render
from django.template.response import SimpleTemplateResponse from django.template.response import SimpleTemplateResponse
from django.utils.deprecation import MiddlewareMixin from django.utils.deprecation import MiddlewareMixin
@ -143,12 +143,19 @@ class CommonErrorMiddleware(MiddlewareMixin):
# to infinite redirects. # to infinite redirects.
return None 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.') message = _('Error running operation.')
else: else:
message = _('Error loading page.') 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( redirect_url = CommonErrorMiddleware._get_redirect_url_on_error(
request) request)
return redirect(redirect_url) return redirect(redirect_url)

View File

@ -9,7 +9,7 @@ import pytest
from django.contrib.auth.models import AnonymousUser, Group, User from django.contrib.auth.models import AnonymousUser, Group, User
from django.core.exceptions import PermissionDenied from django.core.exceptions import PermissionDenied
from django.db.utils import OperationalError from django.db.utils import OperationalError
from django.http import (HttpResponse, HttpResponseNotAllowed, from django.http import (Http404, HttpResponse, HttpResponseNotAllowed,
HttpResponseRedirect) HttpResponseRedirect)
from django.test.client import RequestFactory from django.test.client import RequestFactory
from django.urls import resolve from django.urls import resolve
@ -294,6 +294,18 @@ class TestCommonErrorMiddleware:
assert response.template_name == 'error.html' assert response.template_name == 'error.html'
assert 'message' in response.context_data 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 @staticmethod
@patch('django.contrib.messages.error') @patch('django.contrib.messages.error')
def test_other_error_get(messages_error, middleware, web_request, def test_other_error_get(messages_error, middleware, web_request,