TwitchIO icon indicating copy to clipboard operation
TwitchIO copied to clipboard

TimeoutError in Client.join_channels causes unhandled exception

Open SamChill opened this issue 2 years ago • 6 comments

If Client.join_channels is called and a TimeoutError occurs while trying to join a channel, then an unhandled exception will be raised when this channel is removed from the _initial_channels list, because the channel is not an initial channel, but one passed in via join_channels.

Traceback (most recent call last):
  File "/home/chill/.cache/pypoetry/virtualenvs/timedoutbot-5LVMUk6d-py3.7/lib/python3.7/site-packages/twitchio/websocket.py", line 265, in _join_future_handle
    await asyncio.wait_for(fut, timeout=10)
  File "/home/chill/.pyenv/versions/3.7.1/lib/python3.7/asyncio/tasks.py", line 423, in wait_for
    raise futures.TimeoutError()
concurrent.futures._base.TimeoutError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/chill/.cache/pypoetry/virtualenvs/timedoutbot-5LVMUk6d-py3.7/lib/python3.7/site-packages/twitchio/websocket.py", line 275, in _join_future_handle
    await self._process_data(data)
  File "/home/chill/.cache/pypoetry/virtualenvs/timedoutbot-5LVMUk6d-py3.7/lib/python3.7/site-packages/twitchio/websocket.py", line 284, in _process_data
    return await self._code(parsed, parsed["code"])
  File "/home/chill/.cache/pypoetry/virtualenvs/timedoutbot-5LVMUk6d-py3.7/lib/python3.7/site-packages/twitchio/websocket.py", line 321, in _code
    self._initial_channels.remove(parsed["batches"][0])
ValueError: list.remove(x): x not in list

SamChill avatar Sep 08 '21 23:09 SamChill

When addressing this is it possible to distinguish between actual (network) timeout and a chat timeout/ban? And possibly even create new event_s for each individual outcome?

Commaster avatar Jul 18 '22 14:07 Commaster

This may have already been resolved in one of the recent versions or master. Network timeouts to the websocket are a totally different thing and have their own errors raised.

chillymosh avatar Jul 18 '22 14:07 chillymosh

Still not fixed in 2.4.0: (Either renamed/suspended channel or chat ban)

The channel "%REDACTED%" was unable to be joined. Check the channel is valid.

Followed immediately by:

Task exception was never retrieved
future: <Task finished name='Task-13906' coro=<WSConnection._join_future_handle() done, defined at .../python3.8/site-packages/twitchio/websocket.py:293> exception=ValueError('list.remove(x): x not in list')>
Traceback (most recent call last):
  File ".../python3.8/site-packages/twitchio/websocket.py", line 295, in _join_future_handle
    await asyncio.wait_for(fut, timeout=timeout)
  File ".../python3.8/asyncio/tasks.py", line 501, in wait_for
    raise exceptions.TimeoutError()
asyncio.exceptions.TimeoutError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File ".../python3.8/site-packages/twitchio/websocket.py", line 305, in _join_future_handle
    await self._process_data(data)
  File ".../python3.8/site-packages/twitchio/websocket.py", line 314, in _process_data
    return await self._code(parsed, parsed["code"])
  File ".../python3.8/site-packages/twitchio/websocket.py", line 347, in _code
    self._initial_channels.remove(parsed["batches"][0])
ValueError: list.remove(x): x not in list

P.S. And 🙏 please add event_join_failed or similar to deal with such situations automatically instead of reading the log file eventually. Thank you!

Commaster avatar Aug 10 '22 18:08 Commaster

  1. How many channels are you joining in your initial_channels?
  2. Are you joining any channels manually after event_ready using join_channels() if so then how many channels are there in a single call and how long after the bot has hit event_ready are you calling it?
  3. Is your bot account verified?
  4. Could you also please try using at least 3.9.

I suspect it is point 2 though and you are either calling join_channels too soon after event_ready or you have a large number of channels you are trying to join.

Please provide all of the above information and feel free to join the Discord to discuss further to avoid flooding the comments.

chillymosh avatar Aug 10 '22 18:08 chillymosh

  1. 0, the list is empty (see #290).
  2. Yes, one at a time. In this case it has been at least 30 minutes after event_ready. (Restarting for 2.4.0 update)
  3. No. But I get no issues joining other valid/existing channels. This only happens if you try to join a suspended/renamed/invalid channel or the chat is in subscriber-only mode or the bot account is banned from chat.
  4. I will see if this can be arranged, just using what the distro provides 😅

tl;dr: The first message Check the channel is valid. is correct, the channel is not valid or you are not allowed to join chat. The issue is in handling the 353 code from https://github.com/TwitchIO/TwitchIO/blob/master/twitchio/websocket.py#L301

Commaster avatar Aug 11 '22 02:08 Commaster

Event_ready now fires in 2.4 with empty initial_channels, as per the changelog, although this issue is isolated to calling join_channels manually.

chillymosh avatar Aug 11 '22 04:08 chillymosh

I'm still wondering if it's possible to differentiate chat bans from follower-only and/or subscriber-only chat (if the bot account is not a follower/subscriber). https://dev.twitch.tv/docs/irc/tags#roomstate-tags Not sure if we receive these tags when not allowed to join the room/chat...

The Twitch IRC server sends this message after a bot joins a channel

Commaster avatar Oct 01 '22 19:10 Commaster

If you are banned from a channel you receive the below when joining This is a NOTICE msg

DEBUG:twitchio.websocket: < @msg-id=msg_banned :tmi.twitch.tv NOTICE #channel :You are permanently banned from talking in channel.

If it's in follower only we do receive the following message, where if followers-only is not -1 then it is in follower only mode

@emote-only=0;followers-only=0;r9k=0;room-id=526979188;slow=0;subs-only=0 :tmi.twitch.tv ROOMSTATE #channel

chillymosh avatar Oct 01 '22 19:10 chillymosh

Is this handled and exposed by TwitchIO somehow? Or everything falls to "unable to be joined"?


If it can be exposed before the next release I'd like to add a JoinFailureType Enum argument to the event with all the possibilities...


As well as incorrect channel names or suspended channels, if that has a detectable Twitch response.

Commaster avatar Oct 01 '22 19:10 Commaster