diff --git a/swh/deposit/exception.py b/swh/deposit/exception.py index a5a32f2a..99fcf653 100644 --- a/swh/deposit/exception.py +++ b/swh/deposit/exception.py @@ -1,33 +1,34 @@ # Copyright (C) 2020 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU General Public License version 3, or any later version # See top-level LICENSE file for more information from typing import Dict, Optional from rest_framework.exceptions import APIException from rest_framework.response import Response from rest_framework.views import exception_handler from django.db.utils import OperationalError def custom_exception_handler(exc: APIException, context: Dict) -> Optional[Response]: """Custom deposit exception handler to ensure consistent xml output """ # drf's default exception handler first, to get the standard error response response = exception_handler(exc, context) if isinstance(exc, OperationalError): status = "Database backend maintenance" detail = "Service temporarily unavailable, try again later." data = f""" - - {status} - {detail} - + + {status} + {detail} + """ return Response(data, status=503, content_type="application/xml") return response diff --git a/swh/deposit/tests/api/test_exception.py b/swh/deposit/tests/api/test_exception.py index a3716929..91272cfc 100644 --- a/swh/deposit/tests/api/test_exception.py +++ b/swh/deposit/tests/api/test_exception.py @@ -1,51 +1,54 @@ # Copyright (C) 2020 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU General Public License version 3, or any later version # See top-level LICENSE file for more information from swh.deposit.exception import custom_exception_handler from rest_framework.exceptions import APIException from rest_framework.response import Response from django.db.utils import OperationalError def test_custom_exception_handler_operational_error(mocker): """Operation error are translated to service unavailable """ fake_exception = OperationalError("Fake internal error", 503) response = custom_exception_handler(fake_exception, {}) assert response is not None assert response.content_type == "application/xml" + assert response.status_code == 503 + + status = "Database backend maintenance" + detail = "Service temporarily unavailable, try again later." assert ( response.data - == """ - - Database backend maintenance - Service temporarily unavailable, try again later. - + == f""" + + {status} + {detail} + """ ) - assert response.status_code == 503 - def test_custom_exception_handler_default_behavior_maintained(mocker): """Other internal errors are transmitted as is """ fake_exception = APIException("Fake internal error", 500) fake_response = Response( exception=fake_exception, status=fake_exception.status_code ) mock_exception_handler = mocker.patch("swh.deposit.exception.exception_handler") mock_exception_handler.return_value = fake_response response = custom_exception_handler(fake_exception, {}) assert response is not None assert response == fake_response