diff --git a/plinth/middleware.py b/plinth/middleware.py index 0dec396ba..5a34798b8 100644 --- a/plinth/middleware.py +++ b/plinth/middleware.py @@ -10,8 +10,11 @@ from django.conf import settings 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.shortcuts import render +from django.template.response import SimpleTemplateResponse from django.utils.deprecation import MiddlewareMixin +from django.utils.translation import gettext as _ from stronghold.utils import is_view_func_public from plinth import app as app_module @@ -114,3 +117,19 @@ class FirstSetupMiddleware(MiddlewareMixin): 'refresh_page_sec': 3 } return render(request, 'first_setup.html', context) + + +class CommonErrorMiddleware(MiddlewareMixin): + """Django middleware to handle common errors.""" + + @staticmethod + def process_exception(request, exception): + """Show a custom error page when OperationalError is raised.""" + if isinstance(exception, OperationalError): + message = _( + 'System is possibly under heavy load. Please retry later.') + return SimpleTemplateResponse('error.html', + context={'message': message}, + status=503) + + return None diff --git a/plinth/settings.py b/plinth/settings.py index 882fe688a..6c0e905a8 100644 --- a/plinth/settings.py +++ b/plinth/settings.py @@ -135,6 +135,7 @@ MIDDLEWARE = ( 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', + 'plinth.middleware.CommonErrorMiddleware', 'stronghold.middleware.LoginRequiredMiddleware', 'plinth.middleware.AdminRequiredMiddleware', 'plinth.middleware.FirstSetupMiddleware', diff --git a/plinth/templates/error.html b/plinth/templates/error.html new file mode 100644 index 000000000..fbedd105c --- /dev/null +++ b/plinth/templates/error.html @@ -0,0 +1,16 @@ +{% extends 'base.html' %} +{% comment %} +# SPDX-License-Identifier: AGPL-3.0-or-later +{% endcomment %} + +{% load i18n %} + +{% block content %} + +
+ {{ message }} +
+ +{% endblock %}