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