From 1f980361e3a82bfd133c76633b29ded7e46f4aa8 Mon Sep 17 00:00:00 2001 From: Rapptz Date: Sun, 23 Aug 2015 02:43:04 -0400 Subject: [PATCH] Sandbox events so exceptions being thrown don't break the client. --- discord/client.py | 14 ++++++++++---- docs/api.rst | 4 +++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/discord/client.py b/discord/client.py index 8278330a1..e31c04f5c 100644 --- a/discord/client.py +++ b/discord/client.py @@ -127,12 +127,18 @@ class Client(object): else: return [] + def _invoke_event(self, event_name, *args, **kwargs): + try: + self.events[event_name](*args, **kwargs) + except Exception as e: + pass + def _received_message(self, msg): response = json.loads(str(msg)) if response.get('op') != 0: return - self.events['on_response'](response) + self._invoke_event('on_response', response) event = response.get('t') data = response.get('d') @@ -156,7 +162,7 @@ class Client(object): self.keep_alive = _keep_alive_handler(interval, self.ws) # we're all ready - self.events['on_ready']() + self._invoke_event('on_ready') elif event == 'MESSAGE_CREATE': channel = self.get_channel(data.get('channel_id')) message = Message(channel=channel, **data) @@ -173,7 +179,7 @@ class Client(object): older_message = self._get_message(data.get('id')) if older_message is not None: message = Message(channel=older_message.channel, **data) - self.events['on_message_edit'](older_message, message) + self._invoke_event('on_message_edit', older_message, message) older_message.edited_timestamp = message.edited_timestamp else: # if we couldn't find the message in our cache, just add it to the list @@ -195,7 +201,7 @@ class Client(object): server.members.remove(user) # call the event now - self.events['on_status'](server, user, status, data.get('game_id')) + self._invoke_event('on_status', server, user, status, data.get('game_id')) elif event == 'USER_UPDATE': self.user = User(**data) diff --git a/docs/api.rst b/docs/api.rst index 173964f2f..a161fe971 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -18,6 +18,7 @@ Event Reference ~~~~~~~~~~~~~~~~ This page outlines the different types of events listened to by :meth:`Client.event`. +All events are 'sandboxed', in that if an exception is thrown while the event is called then it is caught and then ignored. .. function:: on_ready() @@ -34,7 +35,8 @@ This page outlines the different types of events listened to by :meth:`Client.ev .. function:: on_response(response) Called whenever a message is received from the websocket. Used mainly for debugging purposes. - The parameter passed is raw data that was parsed via ``json.loads``. + The parameter passed is raw data that was parsed via ``json.loads``. Note that this is called + before the :class:`Client` processes the event. :param response: The received message response after gone through ``json.loads``.