blob: 7d26a57112925f318f9bd18eae068f4aac36a63a [file] [log] [blame]
import logging
import sys
from airavata.api.error.ttypes import (
AuthorizationException,
ExperimentNotFoundException
)
from django.core.exceptions import ObjectDoesNotExist
from django.http import JsonResponse
from rest_framework import status
from rest_framework.exceptions import NotAuthenticated
from rest_framework.response import Response
from rest_framework.views import exception_handler
from thrift.Thrift import TException
from thrift.transport import TTransport
log = logging.getLogger(__name__)
def custom_exception_handler(exc, context):
# Call REST framework's default exception handler first,
# to get the standard error response.
response = exception_handler(exc, context)
if isinstance(exc, AuthorizationException):
log.warning("AuthorizationException", exc_info=exc)
return Response(
{'detail': str(exc)},
status=status.HTTP_403_FORBIDDEN)
if isinstance(exc, ExperimentNotFoundException):
log.warning("ExperimentNotFoundException", exc_info=exc)
return Response(
{'detail': str(exc)},
status=status.HTTP_404_NOT_FOUND)
if isinstance(exc, TTransport.TTransportException):
log.warning("TTransportException", exc_info=exc)
return Response(
{'detail': str(exc), 'apiServerDown': True},
status=status.HTTP_500_INTERNAL_SERVER_ERROR)
# Default TException handler, should come after more specific subclasses of
# TException
if isinstance(exc, TException):
log.error("TException", exc_info=exc, extra={'request': context['request']})
return Response(
{'detail': str(exc)},
status=status.HTTP_500_INTERNAL_SERVER_ERROR)
if isinstance(exc, ObjectDoesNotExist):
log.warning("ObjectDoesNotExist", exc_info=exc)
return Response(
{'detail': str(exc)},
status=status.HTTP_404_NOT_FOUND)
if isinstance(exc, NotAuthenticated):
log.debug("NotAuthenticated", exc_info=exc)
if response is not None:
response.data['is_authenticated'] = False
if isinstance(exc, UnicodeEncodeError):
fse = sys.getfilesystemencoding()
if fse != 'utf-8':
log.error(f"filesystem encoding is {fse}, not 'utf-8'. File paths with Unicode characters will produce errors.")
# Generic handler
if response is None:
log.error("API exception", exc_info=exc, extra={'request': context['request']})
return Response(
{'detail': str(exc)},
status=status.HTTP_500_INTERNAL_SERVER_ERROR
)
return response
# For non-Django REST Framework error responses
def generic_json_exception_response(
exc, status=status.HTTP_500_INTERNAL_SERVER_ERROR):
return JsonResponse({'detail': str(exc)}, status=status)