sclack icon indicating copy to clipboard operation
sclack copied to clipboard

Error on startup: 'NoneType' object is not callable

Open Garethp opened this issue 7 years ago • 11 comments
trafficstars

When I try to start this application, it manages to load the list of channels and chats I have, but then crashed out with the following stacktrace:

Traceback (most recent call last):
  File "./app.py", line 532, in <module>
    app.start()
  File "./app.py", line 53, in start
    self.urwid_loop.run()
  File "/home/gareth/.local/lib/python3.6/site-packages/urwid/main_loop.py", line 286, in run
    self._run()
  File "/home/gareth/.local/lib/python3.6/site-packages/urwid/main_loop.py", line 384, in _run
    self.event_loop.run()
  File "/home/gareth/.local/lib/python3.6/site-packages/urwid/main_loop.py", line 1484, in run
    reraise(*exc_info)
  File "/home/gareth/.local/lib/python3.6/site-packages/urwid/compat.py", line 55, in reraise
    value = tp()
TypeError: 'NoneType' object is not callable

Garethp avatar Aug 07 '18 09:08 Garethp

Thank you for reporting! This is caused by an issue on Urwid (Asyncio event loop) that doesn't handle correctly the context of an exception after capturing it (and this generates another exception hiding the original one). I will be working on this as soon as possible!

haskellcamargo avatar Aug 07 '18 11:08 haskellcamargo

Doing a bit of debugging, here's the exception that it's hiding

{
    'message': 'Task exception was never retrieved', 
    'exception': TypeError("'NoneType' object is not subscriptable",), 
    'future': <Task finished coro=<App.component_did_mount() done, defined at ./app.py:79> exception=TypeError("'NoneType' object is not subscriptable",)>
}

Garethp avatar Aug 07 '18 13:08 Garethp

This happened to me too. I found that the original exception was a KeyError("members") from

https://github.com/haskellcamargo/sclack/blob/8991cb6c69ac9385d139c008ffd6271b38711709/sclack/store.py#L93-L95

The Slack API was returning an invalid auth response because I entered in the wrong token the first time that I ran the program.

Edit: Is there any way to use this app without being an administrator in the Slack workspace to generate a token?

michael-lazar avatar Aug 07 '18 15:08 michael-lazar

I'm not a slack admin, but I was able to generate a token no problem. It's not an Authentication failure in my instance because I can see a list of channels and members for a second right before the errors appear, so it's managing to fetch that information

Garethp avatar Aug 07 '18 15:08 Garethp

I see the same thing, get a list of channels in the left sidebar, then the same stack trace as posted above. I am using a fresh token generated a few minutes ago.

gholmes avatar Aug 07 '18 19:08 gholmes

Happens to me when I open a specific channel.

Traceback (most recent call last):
  File "./app.py", line 556, in <module>
    app.start()
  File "./app.py", line 58, in start
    self.urwid_loop.run()
  File "/home/tun3/.local/lib/python3.6/site-packages/urwid/main_loop.py", line 286, in run
    self._run()
  File "/home/tun3/.local/lib/python3.6/site-packages/urwid/main_loop.py", line 384, in _run
    self.event_loop.run()
  File "/home/tun3/.local/lib/python3.6/site-packages/urwid/main_loop.py", line 1484, in run
    reraise(*exc_info)
  File "/home/tun3/.local/lib/python3.6/site-packages/urwid/compat.py", line 55, in reraise
    value = tp()
TypeError: 'NoneType' object is not callable

lennartkoopmann avatar Aug 08 '18 03:08 lennartkoopmann

In #19, I've overloaded the Asyncio event loop to use the default exception handler, so we can have, at least for now, the original error messages instead of the "error on error" that happens when trying to re-raise an exception. Network errors are predictable due to Slack limits, but an auto-retry feature will be added soon.

haskellcamargo avatar Aug 08 '18 03:08 haskellcamargo

@lennartkoopmann try it in the last version. It will give you the real error message, so we can now investigate.

haskellcamargo avatar Aug 08 '18 03:08 haskellcamargo

So I've done some more debugging, and here's where my error is: In the first (and therefore default) channel, there's a a "User has joined the channel" message with the User Id. Only problem is that said user doesn't exist in the store._user_dict, so store.find_user_by_id returns a None type in app.py:269, and the error then gets thrown when it tries to access the id from it in the next line down

Garethp avatar Aug 08 '18 09:08 Garethp

@Garethp that probably happens because Slack method to get users truncates at 500, and we are still not loading the missing ones. We still need to handle the case when there are "more users to fetch" when loading the users (and also allow to send DMs for unlisted users and groups).

haskellcamargo avatar Aug 08 '18 18:08 haskellcamargo

So, like I said in the PR, for me it wasn't the case (The whole organization has less than 30 people), but rather users that had previously been banned. They get filtered out when the users are populated, but for some reason the "XYZ has joined the Channel" was being fetched by the API even though it wasn't displayed by the Slack Client. Since it was referring to a banned user, and banned users get filtered out, it caused the null pointer

Garethp avatar Aug 09 '18 08:08 Garethp