{"action":"created","issue":{"url":"https://api.github.com/repos/moses-palmer/pynput/issues/108","repository_url":"https://api.github.com/repos/moses-palmer/pynput","labels_url":"https://api.github.com/repos/moses-palmer/pynput/issues/108/labels{/name}","comments_url":"https://api.github.com/repos/moses-palmer/pynput/issues/108/comments","events_url":"https://api.github.com/repos/moses-palmer/pynput/issues/108/events","html_url":"https://github.com/moses-palmer/pynput/issues/108","id":350934016,"node_id":"MDU6SXNzdWUzNTA5MzQwMTY=","number":108,"title":"Question: How is the Exception handling supposed to work?","user":{"login":"RedFantom","id":15170036,"node_id":"MDQ6VXNlcjE1MTcwMDM2","avatar_url":"https://avatars0.githubusercontent.com/u/15170036?v=4","gravatar_id":"","url":"https://api.github.com/users/RedFantom","html_url":"https://github.com/RedFantom","followers_url":"https://api.github.com/users/RedFantom/followers","following_url":"https://api.github.com/users/RedFantom/following{/other_user}","gists_url":"https://api.github.com/users/RedFantom/gists{/gist_id}","starred_url":"https://api.github.com/users/RedFantom/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/RedFantom/subscriptions","organizations_url":"https://api.github.com/users/RedFantom/orgs","repos_url":"https://api.github.com/users/RedFantom/repos","events_url":"https://api.github.com/users/RedFantom/events{/privacy}","received_events_url":"https://api.github.com/users/RedFantom/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":3,"created_at":"2018-08-15T19:24:53Z","updated_at":"2018-08-27T18:00:35Z","closed_at":null,"author_association":"NONE","body":"**Background**\r\nI have a program in which I run multiple Listeners for a long period of time, usually somewhere over half an hour to even over an hour at a time. It is very useful to me if exceptions anywhere in the program are reported immediately, as for most parts of the code unittests is not possible (given the structure and nature of the program), so I can debug issues as soon as I see them appear.\r\n\r\nCurrently, the pynput Listeners hide the exceptions from me, completely. I lost quite a bit of time tracking down the issue to the pynput Listeners. I was a bit disappointed when I discovered that I can only catch the errors upon joining a Thread, which is only done after I have performed a testing session.\r\n\r\n**Observed Behaviour**\r\nUsing my fork of the repository, I have determined the behaviour to be the following:\r\n`lib/pynput/_utils/__init__.py`\r\n```python\r\n@classmethod\r\ndef _emitter(cls, f):\r\n    @functools.wraps(f)\r\n    def inner(self, *args, **kwargs):\r\n        try:\r\n            return f(self, *args, **kwargs)  # Call the callback for the event\r\n        except Exception as e:  # Exception occurred in callback\r\n            if not isinstance(e, self._HANDLED_EXCEPTIONS):\r\n                # Schedule for raising upon .join()\r\n                self._queue.put(\r\n                    None if isinstance(e, cls.StopException)\r\n                    else sys.exc_info())\r\n                self.stop()  # Cleanup\r\n            # XXX Never reached\r\n            raise\r\n    return inner\r\n```\r\n\r\n**Expected Behaviour**\r\nI am not familiar with Threading daemons, but I would expect the error to be re-raised at the end of the `try-except`-block. However, the `raise` point is never reached, thus I do not see anything appear on `stderr`. Is this the desired behaviour? Because of it is, I would like propose a PR for my branch of the repository.\r\n\r\n**Other Details**\r\nOperating System: Ubuntu 18.04 64-bit\r\nBack-end: Xorg"},"comment":{"url":"https://api.github.com/repos/moses-palmer/pynput/issues/comments/416313520","html_url":"https://github.com/moses-palmer/pynput/issues/108#issuecomment-416313520","issue_url":"https://api.github.com/repos/moses-palmer/pynput/issues/108","id":416313520,"node_id":"MDEyOklzc3VlQ29tbWVudDQxNjMxMzUyMA==","user":{"login":"RedFantom","id":15170036,"node_id":"MDQ6VXNlcjE1MTcwMDM2","avatar_url":"https://avatars0.githubusercontent.com/u/15170036?v=4","gravatar_id":"","url":"https://api.github.com/users/RedFantom","html_url":"https://github.com/RedFantom","followers_url":"https://api.github.com/users/RedFantom/followers","following_url":"https://api.github.com/users/RedFantom/following{/other_user}","gists_url":"https://api.github.com/users/RedFantom/gists{/gist_id}","starred_url":"https://api.github.com/users/RedFantom/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/RedFantom/subscriptions","organizations_url":"https://api.github.com/users/RedFantom/orgs","repos_url":"https://api.github.com/users/RedFantom/repos","events_url":"https://api.github.com/users/RedFantom/events{/privacy}","received_events_url":"https://api.github.com/users/RedFantom/received_events","type":"User","site_admin":false},"created_at":"2018-08-27T18:00:35Z","updated_at":"2018-08-27T18:00:35Z","author_association":"NONE","body":"Coding errors happen, and having them hidden away for a long time and even then not knowing where to start debugging it is just an experience I think others would like to avoid as well. Exceptions that you expect should always be prevented, it's the unexpected you really want to know about.\r\n\r\nRequiring the user to wrap the callbacks in `try/except` blocks and printing the traceback to stdout or somehow pass it to a place where it is *not* caught by the `try/except` block in the `pynput` library without an option to turn it off is, in my opinion, a weird design choice. It's not that I don't appreciate errors being passed to the `MainThread`, it's the difficulty of preventing the `pynput` library from grabbing it in the first place that I do not quite agree with.\r\n\r\nStill, it appears we differ in opinion on that topic, and thus I will simply use my own fork of the library instead. Thank you for your time."}}
{"actor":{"display_login":"RedFantom"}}