Manishearth / ChatExchange

A Python API for talking to Stack Exchange chat
Apache License 2.0
65 stars 36 forks source link

Posting to a frozen room should fail, but doesn't #164

Closed tripleee closed 10 months ago

tripleee commented 3 years ago

I hit this in https://github.com/tripleee/sloshy/issues/14 and I can't seem to find a good way to fix it in the current code.

In brief, when using repl I get a warning about an exception after a short while, but it's unclear to me where in the call stack it happens.

chatexchange == <module 'chatexchange' from '/home/tripleee/git/ChatExchange/chatexchange/__init__.py'>
host == 'stackexchange.com'
# email: ******************
# password: Password: 
chat == <chatexchange.client.Client object at 0x109cc99a0>
sandbox == <chatexchange.rooms.Room object at 0x109ce0be0>
me == <chatexchange.users.User object at 0x109cec250>
me.name == 'sloshy'

bpython version 0.21 on top of Python 3.8.2 /home/tripleee/git/ChatExchange/venv/bin/python3
>>> chat.host
'stackexchange.com'
>>> chat.get_room(111121)
<chatexchange.rooms.Room object at 0x109d9a040>
>>> r = chat.get_room(111121)
>>> r.description
''
>>> me.room_count
26
>>> r.send_message('nst')
Exception in thread Exception in threading.excepthook:Exception ignored in threa
d started byException ignored in sys.unraisablehook>>> 

In the linked ticket, there is a slightly more informative traceback, but its root is a thread which isn't connected to the calling code. I'll see if I can figure out where exactly the 404 in that particular traceback is being caught.

tripleee commented 3 years ago

I'm getting a slightly better traceback with this simple demo.

#!/usr/bin/env python3

from os import environ as env
from time import sleep

from chatexchange.client import Client

client = Client('stackexchange.com', env['CHAT_EMAIL'], env['CHAT_PASSWORD'])
room = client.get_room(111121)
room.send_message('Testing')
q = client._request_queue
while not q.empty():
    print("waiting for queue to drain (%i items in queue)" % q.qsize())
    sleep(15)
client.logout()

Without the loop to wait for the queue to drain, it just quits with no indication of any error at the end of the script. (I have been wishing for other reasons that an explicit logout should make sure all messages are delivered before it disconnects, but I digress.)

The traceback shows that raise_for_status() is actually being called correctly, but there is no longer any obvious way at this point to relay the status back to the calling client.

waiting for queue to drain (1 items in queue)
Exception in thread message_sender:
Traceback (most recent call last):
  File "/home/tripleee/.pyenv/versions/3.8.2/lib/python3.8/threading.py", line 932, in _bootstrap_inner
    self.run()
  File "/home/tripleee/.pyenv/versions/3.8.2/lib/python3.8/threading.py", line 870, in run
    self._target(*self._args, **self._kwargs)
  File "/home/tripleee/git/sloshy/venv/lib/python3.8/site-packages/chatexchange/client.py", line 183, in _worker
    self._do_action_despite_throttling(next_action)
  File "/home/tripleee/git/sloshy/venv/lib/python3.8/site-packages/chatexchange/client.py", line 221, in _do_action_despite_throttling
    response = self._br.send_message(room_id, text)
  File "/home/tripleee/git/sloshy/venv/lib/python3.8/site-packages/chatexchange/browser.py", line 299, in send_message
    return self.post_fkeyed(
  File "/home/tripleee/git/sloshy/venv/lib/python3.8/site-packages/chatexchange/browser.py", line 133, in post_fkeyed
    return self.post(url, data, headers)
  File "/home/tripleee/git/sloshy/venv/lib/python3.8/site-packages/chatexchange/browser.py", line 113, in post
    return self._request('post', url, data, headers, with_chat_root)
  File "/home/tripleee/git/sloshy/venv/lib/python3.8/site-packages/chatexchange/browser.py", line 102, in _request
    response.raise_for_status()
  File "/home/tripleee/git/sloshy/venv/lib/python3.8/site-packages/requests/models.py", line 943, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 404 Client Error: Not Found for url: https://chat.stackexchange.com/chats/111121/messages/new
tripleee commented 3 years ago

https://stackoverflow.com/questions/2829329/catch-a-threads-exception-in-the-caller-thread has some ideas to explore. Ultimately perhaps an async solution would be more manageable and robust, but then that would entail giving up compatibility with Python 2 and older versions of Python 3.