Repository: apache/superset
File: superset/utils/slack.py (Python)

Code before:
        raise


def get_channels_with_search(
    search_string: str = "",
    types: Optional[list[SlackChannelTypes]] = None,
    exact_match: bool = False,
    force: bool = False,
) -> list[SlackChannelSchema]:
    """
    The slack api is paginated but does not include search, so we need to fetch
    all channels and filter them ourselves
    This will search by slack name or id
    """
    try:
        channels = get_channels(
            force=force,
            cache_timeout=app.config["SLACK_CACHE_TIMEOUT"],
        )
    except SlackApiError as ex:
        # Check if it's a rate limit error
        if ex.response and ex.response.status_code == 429:
            raise SupersetException(
                f"Slack API rate limit exceeded: {ex}. "
                "For large workspaces (10k+ channels), consider increasing "
                "SLACK_API_RATE_LIMIT_RETRY_COUNT (current default: 5, try 10) "
                "and SLACK_CACHE_TIMEOUT (recommended: 7 days). "
                "Consider using the slack.cache_channels Celery task "
                "to warm up the cache."
            ) from ex
        raise SupersetException(f"Failed to list channels: {ex}") from ex
    except SlackClientError as ex:
        raise SupersetException(f"Failed to list channels: {ex}") from ex

    if types and not len(types) == len(SlackChannelTypes):
        conditions: list[Callable[[SlackChannelSchema], bool]] = []
        if SlackChannelTypes.PUBLIC in types:
            conditions.append(lambda channel: not channel["is_private"])
        if SlackChannelTypes.PRIVATE in types:
            conditions.append(lambda channel: channel["is_private"])

        channels = [
            channel for channel in channels if any(cond(channel) for cond in conditions)
        ]

    # The search string can be multiple channels separated by commas
    if search_string:
        search_array = recipients_string_to_list(search_string)
        channels = [
            channel
            for channel in channels

Review comment (bug):
Don't hardcode values, what if the user is already at 10 or something else, this exception message is now wrong.

Code after:
        raise


def get_channels_with_search(
    search_string: str = "",
    types: Optional[list[SlackChannelTypes]] = None,
    exact_match: bool = False,
    force: bool = False,
) -> list[SlackChannelSchema]:
    """
    The slack api is paginated but does not include search, so we need to fetch
    all channels and filter them ourselves
    This will search by slack name or id
    """
    try:
        channels = get_channels(
            force=force,
            cache_timeout=app.config["SLACK_CACHE_TIMEOUT"],
        )
    except SlackApiError as ex:
        # Check if it's a rate limit error
        status_code = getattr(ex.response, "status_code", None)
        if status_code == 429:
            raise SupersetException(
                f"Slack API rate limit exceeded: {ex}. "
                "For large workspaces, consider increasing "
                "SLACK_API_RATE_LIMIT_RETRY_COUNT"
            ) from ex
        raise SupersetException(f"Failed to list channels: {ex}") from ex
    except SlackClientError as ex:
        raise SupersetException(f"Failed to list channels: {ex}") from ex

    if types and not len(types) == len(SlackChannelTypes):
        conditions: list[Callable[[SlackChannelSchema], bool]] = []
        if SlackChannelTypes.PUBLIC in types:
            conditions.append(lambda channel: not channel["is_private"])
        if SlackChannelTypes.PRIVATE in types:
            conditions.append(lambda channel: channel["is_private"])

        channels = [
            channel for channel in channels if any(cond(channel) for cond in conditions)
        ]

    # The search string can be multiple channels separated by commas
    if search_string:
        search_array = recipients_string_to_list(search_string)
        channels = [
            channel
            for channel in channels
            if any(
                (