Catch-all decorator that handles AutoReconnect and OperationFailure
    errors from PyMongo

def mongo_retry(f):
    """
    Catch-all decorator that handles AutoReconnect and OperationFailure
    errors from PyMongo
    """
    log_all_exceptions = 'arctic' in f.__module__ if f.__module__ else False

    @wraps(f)
    def f_retry(*args, **kwargs):
        global _retry_count, _in_retry
        top_level = not _in_retry
        _in_retry = True
        try:
            while True:
                try:
                    return f(*args, **kwargs)
                except (DuplicateKeyError, ServerSelectionTimeoutError) as e:
                    # Re-raise errors that won't go away.
                    _handle_error(f, e, _retry_count, **_get_host(args))
                    raise
                except (OperationFailure, AutoReconnect) as e:
                    _retry_count += 1
                    _handle_error(f, e, _retry_count, **_get_host(args))
                except Exception as e:
                    if log_all_exceptions:
                        _log_exception(f.__name__, e, _retry_count, **_get_host(args))
                    raise
        finally:
            if top_level:
                _in_retry = False
                _retry_count = 0
    return f_retry