diff --git a/swh/deposit/exception.py b/swh/deposit/exception.py
index 99fcf653..cdd1f7d0 100644
--- a/swh/deposit/exception.py
+++ b/swh/deposit/exception.py
@@ -1,34 +1,38 @@
# 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.http import HttpResponse
from django.db.utils import OperationalError
-def custom_exception_handler(exc: APIException, context: Dict) -> Optional[Response]:
+def custom_exception_handler(
+ exc: APIException, context: Dict
+) -> Optional[HttpResponse]:
"""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}
-"""
- return Response(data, status=503, content_type="application/xml")
+""".encode(
+ "utf-8"
+ )
+ return HttpResponse(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 91272cfc..0d71926b 100644
--- a/swh/deposit/tests/api/test_exception.py
+++ b/swh/deposit/tests/api/test_exception.py
@@ -1,54 +1,53 @@
# 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
+ response.content.decode("utf-8")
== f"""
{status}
{detail}
"""
)
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