
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
Add additional error detail to cover other circumstances that intend to throw 401
