
from rest_framework import status
from rest_framework.exceptions import APIException


def json_api_exception_handler(exc, context):
    """
    Custom exception handler that returns errors object as an array
    """
    from rest_framework.views import exception_handler
    response = exception_handler(exc, context)

    # Title removed to avoid clash with node "title" errors
    acceptable_members = ['id', 'links', 'status', 'code', 'detail', 'source', 'meta']
    errors = []

    if response is not None:
        message = response.data
        if isinstance(message, dict):
            for key, value in message.iteritems():
                if key in acceptable_members:
                    errors.append({key: value})
                else:
                    errors.append({'detail': {key: value}})
        elif isinstance(message, list):
            for error in message:
                errors.append({'detail': error})
        else:
            errors.append({'detail': message})

    response.data = {'errors': errors}

    # Return 401 instead of 403 during unauthorized requests without having user log in with Basic Auth
    if response is not None and response.data['errors'][0].get('detail') == "Authentication credentials were not provided.":
        response.status_code = 401

    return response


# Custom Exceptions the Django Rest Framework does not support
class Gone(APIException):
    status_code = status.HTTP_410_GONE
    default_detail = ('The requested resource is no longer available.')


from rest_framework import status
from rest_framework.exceptions import APIException


def json_api_exception_handler(exc, context):
    """
    Custom exception handler that returns errors object as an array
    """
    from rest_framework.views import exception_handler
    response = exception_handler(exc, context)

    # Title removed to avoid clash with node "title" errors
    acceptable_members = ['id', 'links', 'status', 'code', 'detail', 'source', 'meta']
    errors = []

    if response is not None:
        message = response.data
        if isinstance(message, dict):
            for key, value in message.iteritems():
                if key in acceptable_members:
                    errors.append({key: value})
                else:
                    errors.append({'detail': {key: value}})
        elif isinstance(message, list):
            for error in message:
                errors.append({'detail': error})
        else:
            errors.append({'detail': message})

    response.data = {'errors': errors}

    # Return 401 instead of 403 during unauthorized requests without having user log in with Basic Auth
    error_message = response.data['errors'][0].get('detail')
    errors_401 = ["Authentication credentials were not provided.", 'Incorrect authentication credentials.']

    if response is not None and error_message in errors_401:
        response.status_code = 401

    return response


# Custom Exceptions the Django Rest Framework does not support
class Gone(APIException):
    status_code = status.HTTP_410_GONE
    default_detail = ('The requested resource is no longer available.')

Add additional error detail to cover other circumstances that intend to throw 401