diff --git a/pydle/client.py b/pydle/client.py index dc3296a..67f47fa 100644 --- a/pydle/client.py +++ b/pydle/client.py @@ -341,8 +341,9 @@ class BasicClient: message = self._parse_message() self.on_raw(message) - def on_data_error(self): + def on_data_error(self, exception): """ Handle error. """ + self.logger.error('Encountered error on socket. Reconnecting.', exc_info=(type(exception), exception, None)) self.disconnect() def on_raw(self, message): diff --git a/pydle/connection.py b/pydle/connection.py index 7f05f4d..b7003ed 100644 --- a/pydle/connection.py +++ b/pydle/connection.py @@ -1,4 +1,5 @@ import sys +import os import os.path as path import collections import time @@ -276,7 +277,14 @@ class Connection: ## Lower-level data-related methods. def on(self, method, callback): - """ Add callback for event. """ + """ + Add callback for event. + + Handlers are called as follows: + - read: Called with the read data. + - write: Called with the a list of the written messages. + - error: Called with the exception that occurred. + """ if method not in self.handlers: raise ValueError('Given method must be one of: {}'.format(', '.join(self.handlers))) self.handlers[method].append(callback) @@ -386,5 +394,13 @@ class Connection: self.update_write_handler() def _on_error(self, fd): + # Get native error and create exception from it. + errno = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR) + try: + message = os.strerror(errno) + except ValueError: + message = 'Unknown error' + exception = IOError(errno, message) + for handler in self.handlers['error']: - handler() + handler(exception)