Hi! We're currently running the asyncio branch of discord.py in our app, and we grabbed the latest code from git as of March 7th (~2 weeks ago), or version 0.10.0_alpha (because we started writing this app before the asyncio branch was the default or released on PyPi, as I think is the case now).
After a while (and fairly randomly), we seem to run into these errors when trying to send messages:
DEBUG:discord.client:In send_message, POST https://discordapp.com/api/channels/134020776251752448/messages has returned 502
ERROR:asyncio:Task exception was never retrieved
future: <Task finished coro=<send_message() done, defined at /home/itabashi/itabashi/env/lib/python3.4/site-packages/discord/client.py:903> exception=HTTPException('Bad Gateway (status code: 502)',)>
Traceback (most recent call last):
File "/usr/lib/python3.4/asyncio/tasks.py", line 235, in _step
result = coro.send(value)
File "/home/itabashi/itabashi/env/lib/python3.4/site-packages/discord/client.py", line 964, in send_message
yield from utils._verify_successful_response(resp)
File "/home/itabashi/itabashi/env/lib/python3.4/site-packages/discord/utils.py", line 192, in _verify_successful_response
raise HTTPException(response, message, text)
discord.errors.HTTPException: Bad Gateway (status code: 502)
And then every message we try to send from that point onwards results in this:
Traceback (most recent call last):
File "/usr/lib/python3.4/asyncio/tasks.py", line 237, in _step
result = next(coro)
File "/home/itabashi/itabashi/env/lib/python3.4/site-packages/discord/client.py", line 963, in send_message
resp = yield from self._rate_limit_helper('send_message', 'POST', url, utils.to_json(payload))
File "/home/itabashi/itabashi/env/lib/python3.4/site-packages/discord/client.py", line 891, in _rate_limit_helper
resp = yield from self.session.request(method, url, data=data, headers=self.headers)
File "/home/itabashi/itabashi/env/lib/python3.4/site-packages/aiohttp/client.py", line 528, in __iter__
resp = yield from self._coro
File "/home/itabashi/itabashi/env/lib/python3.4/site-packages/aiohttp/client.py", line 150, in _request
raise RuntimeError('Session is closed')
RuntimeError: Session is closed
The main issue is that we don't receive an on_socket_closed event or something similar to just reconnect ourselves, and I can't see any issues in the logs leading up to those errors.
We're trying to track down some more info on this ourselves, but if you need anything else give me a yell. We've got full debug logs with all the messages like this, if it could help:
DEBUG:discord.client:POST https://discordapp.com/api/auth/login has returned 200
INFO:discord.client:logging in returned status code 200
...etc...
Thanks for making the library, it's been a huge help!
This is "expected behavior" when running the client. There is no reconnect logic, and when the websocket connection dies for pretty much any reason it will close the client. Client.close() involves closing the aiohttp session used for all HTTPS requests, and this is _never_ recreated again, and as such, you can't use the Client object any more unless you recreate the aiohttp session in a similar fashion to how it's done in __init__.
I currently do something similar to this to keep my bot running despite every attempt Discord.py does to stop it.
Hmm, we never call Client.close(), so I'm guessing either discord.py or aiohttp itself closes it without dispatching an on_socket_closed event or something similar for us to catch. I'm guessing we'll probably need to wrap the message sending function as well and force a reconnection when that second error above pops up?
Thanks very much for the code, outlines what you mean. Does it have any license I should be aware of? (GPL2+ project)
Client.close() is invoked by Client.connect() before it returns when the websocket is closed. If you use the Client.sane_connect() method defined in my code, Client.close() will not be called, so you don't need to worry about the aiohttp session being closed.
You may use the code I provided for any purpose, though thanks for asking about that (including relicensing it to GPL2+).
Also want to point out that there is no on_socket_closed event. There used to be one in v0.9, but as noted in the migration guide it was removed in the asyc branch.
Oh I see, that code makes a lot more sense then. Thanks!
Ah, think I wrote that code before that note was added to the migration guide. Will rip that out!
Oh I see I thought that it was still there too. Will use or try to use what Horn Said in my bot somehow :+1:
@AraHaan We started using this message loop in our bot and we've received none of these disconnection errors on the Discord side since then. Large improvement.
Most helpful comment
Oh I see I thought that it was still there too. Will use or try to use what Horn Said in my bot somehow :+1: