diff --git a/modoboa/core/commands/templates/settings.py.tpl b/modoboa/core/commands/templates/settings.py.tpl index 67a373831..2ac1ab179 100644 --- a/modoboa/core/commands/templates/settings.py.tpl +++ b/modoboa/core/commands/templates/settings.py.tpl @@ -118,6 +118,7 @@ MIDDLEWARE = ( 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'modoboa.core.middleware.LocalConfigMiddleware', + 'modoboa.lib.middleware.CommonExceptionCatcher', 'modoboa.lib.middleware.RequestCatcherMiddleware', ) diff --git a/modoboa/lib/middleware.py b/modoboa/lib/middleware.py index f679b6287..64d5ef237 100644 --- a/modoboa/lib/middleware.py +++ b/modoboa/lib/middleware.py @@ -1,8 +1,30 @@ """Custom middlewares.""" +from django.http import JsonResponse from django.utils.deprecation import MiddlewareMixin +from django.utils.encoding import smart_str from modoboa.lib import signals as lib_signals +from modoboa.lib.exceptions import ModoboaException +from modoboa.lib.web_utils import _render_error + + +def is_ajax(request): + return request.META.get("HTTP_X_REQUESTED_WITH") == "XMLHttpRequest" + + +class CommonExceptionCatcher(MiddlewareMixin): + """Modoboa exceptions catcher.""" + + def process_exception(self, request, exception): + if not isinstance(exception, ModoboaException): + return None + + if "/api/" in request.path: + http_code = exception.http_code if exception.http_code else 500 + return JsonResponse({"error": str(exception)}, status=http_code) + + return _render_error(request, user_context={"error": smart_str(exception)}) class RequestCatcherMiddleware(MiddlewareMixin): diff --git a/modoboa/lib/web_utils.py b/modoboa/lib/web_utils.py index 76ad31eef..a0fb97266 100644 --- a/modoboa/lib/web_utils.py +++ b/modoboa/lib/web_utils.py @@ -2,6 +2,14 @@ import re +from django.shortcuts import render + + +def _render_error(request, errortpl="error", user_context=None): + if user_context is None: + user_context = {} + return render(request, f"common/{errortpl}.html", user_context) + def size2integer(value: str, output_unit: str = "B") -> int: """ diff --git a/test_project/test_project/settings.py b/test_project/test_project/settings.py index ba5cd11d7..762308a78 100644 --- a/test_project/test_project/settings.py +++ b/test_project/test_project/settings.py @@ -129,6 +129,7 @@ MIDDLEWARE = ( "django.contrib.messages.middleware.MessageMiddleware", "django.middleware.clickjacking.XFrameOptionsMiddleware", "modoboa.core.middleware.LocalConfigMiddleware", + "modoboa.lib.middleware.CommonExceptionCatcher", "modoboa.lib.middleware.RequestCatcherMiddleware", )