django_airavata/apps/api/exceptions.py (60 lines of code) (raw):

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)