PythonistaGuild / TwitchIO

An Async Bot/API wrapper for Twitch made in Python.
https://twitchio.dev
MIT License
785 stars 163 forks source link

Handling :tmi.twitch.tv NOTICE * :Login unsuccessful #404

Open Commaster opened 1 year ago

Commaster commented 1 year ago

So twitch is having another stroke and 90% of the connection attempts receive this IRC message. But TwitchIO (latest master commit) fails to correctly handle it and the Client.run() method I'm using never returns or raises. Instead we get this from asyncio:

ERROR:asyncio:Exception in callback WSConnection._task_callback(':tmi.twitch....h.tv/commands')(<Task cancell...ocket.py:341>>)
handle: <Handle WSConnection._task_callback(':tmi.twitch....h.tv/commands')(<Task cancell...ocket.py:341>>)>
Traceback (most recent call last):
  File ".../websocket.py", line 341, in _process_data
    async def _process_data(self, data: str):
asyncio.exceptions.CancelledError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3.10/asyncio/events.py", line 80, in _run
    self._context.run(self._callback, *self._args)
  File ".../websocket.py", line 198, in _task_callback
    exc = task.exception()
asyncio.exceptions.CancelledError
ERROR:asyncio:Exception in callback WSConnection._task_callback(':tmi.twitch.... unsuccessful')(<Task cancell...ocket.py:341>>)
handle: <Handle WSConnection._task_callback(':tmi.twitch.... unsuccessful')(<Task cancell...ocket.py:341>>)>
Traceback (most recent call last):
  File ".../websocket.py", line 344, in _process_data
    return await self._close()
  File ".../websocket.py", line 606, in _close
    await self._websocket.close()
  File ".../lib/python3.10/site-packages/aiohttp/client_ws.py", line 172, in close
    await self._waiting
asyncio.exceptions.CancelledError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3.10/asyncio/events.py", line 80, in _run
    self._context.run(self._callback, *self._args)
  File ".../websocket.py", line 198, in _task_callback
    exc = task.exception()
asyncio.exceptions.CancelledError
github-actions[bot] commented 1 year ago

Hello! Thanks for the issue. If this is a general help question, for a faster response consider joining the official Discord Server

Else if you have an issue with the library please wait for someone to help you here.

chillymosh commented 1 year ago

Notices are handled in master by dispatching to the event. Check for this message and then perform whatever action you wish to do. E.g. stop the bot booting up as you must have an invalid token.

Assuming this is start up since you mention Client.run() as well as not being a commands Bot. If this during runtime after RECONNECT then you haven't refreshed your token.

Commaster commented 1 year ago

token is valid since it passes the HTTP validate test each time and also connects correctly sometimes (~ 10% of the attempts). Yes, this at startup, so I have to Ctrl+C the app and restart each time this happens.

Btw, this is a special NOTICE which is handled before the action selection: https://github.com/TwitchIO/TwitchIO/blob/master/twitchio/websocket.py#L349

chillymosh commented 1 year ago

So this wouldn't be related to master, it would be to all versions. Although I never have a 90%, fail rate and if it was that consistent for everyone they would have raised an issue by now.

Commaster commented 1 year ago

This only happens when Twitch itself is having server issues, so you have to try over and over and eventually it'll work. 90% is just my guesstimate. I can reproduce this issue with a desktop IRC client as well: After several reconnects it'll let me it.

chillymosh commented 1 year ago

Okay that makes more sense, thanks. Finding a window to test a potential fix for this on would be difficult.

Commaster commented 1 year ago

Wouldn't it be sufficient to just feed the app :tmi.twitch.tv NOTICE * :Login unsuccessful as the first data line to trigger that special handling? I understand that we can't fix all connection issues, but maybe it's possible to fix this asyncio Error and raise something inside Client/Bot? This would correctly terminate .run(), enabling the users to handle this login failure in some way (either accept it or re-run .run()).

EvieePy commented 1 year ago

In this case it doesn't make sense to terminate the bot and restart. If the token has passed validation it makes more sense to allow a backoff to handle it until it can successfully resume.

raimannma commented 1 year ago

I have the same issue!

chillymosh commented 1 year ago

I believe this could be related to the Summer Games Showcase event that started on June 8 and the Twitch services would have been overloaded causing connection issues. This hasn't really ever been an issue, as far as I know, up until this event, otherwise we would have probably encountered this more regularly. We'll look into potentially adding an exponential backoff reconnect.

raimannma commented 1 year ago

still get this sometimes