def marqo_base_exception_handler(request: Request, exc: base_exceptions.MarqoError) -> JSONResponse:
    """
    Catch a base/core Marqo Error and convert to its corresponding API Marqo Error.
    The API Error will be passed to the `marqo_api_exception_handler` below.
    This ensures that raw base errors are never returned by the API.

    Mappings are in an ordered list to allow for hierarchical resolution of errors.
    Stored as 2-tuples: (Base/Core/Vespa/Inference Error, API Error)
    """
    api_exception_mappings = [
        # More specific errors should take precedence

        # Core exceptions
        (core_exceptions.InvalidFieldNameError, api_exceptions.InvalidFieldNameError, None, None),
        (core_exceptions.IndexExistsError, api_exceptions.IndexAlreadyExistsError, None, None),
        (core_exceptions.IndexNotFoundError, api_exceptions.IndexNotFoundError, None, None),
        (core_exceptions.VespaDocumentParsingError, api_exceptions.BackendDataParsingError, None, None),
        (core_exceptions.OperationConflictError, api_exceptions.OperationConflictError, None, None),
        (core_exceptions.BackendCommunicationError, api_exceptions.BackendCommunicationError, None, None),
        (core_exceptions.ZeroMagnitudeVectorError, api_exceptions.BadRequestError, None, None),
        (core_exceptions.BackendCommunicationError, api_exceptions.BackendCommunicationError, None, None),
        (core_exceptions.UnsupportedFeatureError, api_exceptions.BadRequestError, None, None),
        (core_exceptions.InternalError, api_exceptions.InternalError, None, None),
        (core_exceptions.ApplicationRollbackError, api_exceptions.ApplicationRollbackError, None, None),
        (core_exceptions.TooManyFieldsError, api_exceptions.BadRequestError, None, None),
        (core_exceptions.DeviceError, api_exceptions.ServiceUnavailableError, None, None),

        # Vespa client exceptions
        (
            vespa_exceptions.VespaTimeoutError,
            api_exceptions.VectorStoreTimeoutError,
            "Vector store request timed out. Try your request again later.",
            None
        ),

        # Base exceptions
        (base_exceptions.InternalError, api_exceptions.InternalError, None, None),
        (base_exceptions.InvalidArgumentError, api_exceptions.InvalidArgError, None, None),

        # Inference exceptions
        # TODO - Inference Server currently only raises InferenceError in the remote model, so these two catches
        # TODO - are not used in the remote mode. But they will be used in the combined mode.
        (inference_exceptions.MediaDownloadError, api_exceptions.InvalidArgError, None, None),
        (inference_exceptions.ModelError, api_exceptions.BadRequestError, None, marqo_docs.list_of_models()),
        # TODO - Distinguish recoverable vs unrecoverable errors for InferenceError
        (inference_exceptions.InferenceError, api_exceptions.InvalidArgError, None, None),
    ]

    converted_error = None
    for base_exception, api_exception, message, link in api_exception_mappings:
        if isinstance(exc, base_exception):
            error_message = message or exc.message
            converted_error = api_exception(message=error_message, link=link)
            break

    # Completely unhandled exception (500)
    # This should abstract away internal error.
    if not converted_error:
        converted_error = api_exceptions.MarqoWebError("Marqo encountered an unexpected internal error.")

    return marqo_api_exception_handler(request, converted_error)

    Catch a base/core Marqo Error and convert to its corresponding API Marqo Error.
    The API Error will be passed to the `marqo_api_exception_handler` below.
    This ensures that raw base errors are never returned by the API.

    Mappings are in an ordered list to allow for hierarchical resolution of errors.
    Stored as 2-tuples: (Base/Core/Vespa/Inference Error, API Error)
    
src/marqo/tensor_search/api.py