diff --git a/telethon/extensions/tcp_client.py b/telethon/extensions/tcp_client.py index dd177aa2..d9cea2f0 100644 --- a/telethon/extensions/tcp_client.py +++ b/telethon/extensions/tcp_client.py @@ -2,6 +2,7 @@ This module holds a rough implementation of the C# TCP client. """ import errno +import logging import socket import time from datetime import timedelta @@ -19,6 +20,8 @@ CONN_RESET_ERRNOS = { errno.EINVAL, errno.ENOTCONN } +__log__ = logging.getLogger(__name__) + class TcpClient: """A simple TCP client to ease the work with sockets and proxies.""" @@ -75,6 +78,7 @@ class TcpClient: self._socket.connect(address) break # Successful connection, stop retrying to connect except OSError as e: + __log__.info('OSError "%s" raised while connecting', e) # Stop retrying to connect if proxy connection error occurred if socks and isinstance(e, socks.ProxyConnectionError): raise @@ -120,19 +124,22 @@ class TcpClient: :param data: the data to send. """ if self._socket is None: - self._raise_connection_reset() + self._raise_connection_reset(None) # TODO Timeout may be an issue when sending the data, Changed in v3.5: # The socket timeout is now the maximum total duration to send all data. try: self._socket.sendall(data) except socket.timeout as e: + __log__.debug('socket.timeout "%s" while writing data', e) raise TimeoutError() from e - except ConnectionError: - self._raise_connection_reset() + except ConnectionError as e: + __log__.info('ConnectionError "%s" while writing data', e) + self._raise_connection_reset(e) except OSError as e: + __log__.info('OSError "%s" while writing data', e) if e.errno in CONN_RESET_ERRNOS: - self._raise_connection_reset() + self._raise_connection_reset(e) else: raise @@ -144,7 +151,7 @@ class TcpClient: :return: the read data with len(data) == size. """ if self._socket is None: - self._raise_connection_reset() + self._raise_connection_reset(None) # TODO Remove the timeout from this method, always use previous one with BufferedWriter(BytesIO(), buffer_size=size) as buffer: @@ -153,17 +160,22 @@ class TcpClient: try: partial = self._socket.recv(bytes_left) except socket.timeout as e: + # These are somewhat common if the server has nothing + # to send to us, so use a lower logging priority. + __log__.debug('socket.timeout "%s" while reading data', e) raise TimeoutError() from e - except ConnectionError: - self._raise_connection_reset() + except ConnectionError as e: + __log__.info('ConnectionError "%s" while reading data', e) + self._raise_connection_reset(e) except OSError as e: + __log__.info('OSError "%s" while reading data', e) if e.errno in CONN_RESET_ERRNOS: - self._raise_connection_reset() + self._raise_connection_reset(e) else: raise if len(partial) == 0: - self._raise_connection_reset() + self._raise_connection_reset(None) buffer.write(partial) bytes_left -= len(partial) @@ -172,7 +184,8 @@ class TcpClient: buffer.flush() return buffer.raw.getvalue() - def _raise_connection_reset(self): + def _raise_connection_reset(self, original): """Disconnects the client and raises ConnectionResetError.""" self.close() # Connection reset -> flag as socket closed - raise ConnectionResetError('The server has closed the connection.') + raise ConnectionResetError('The server has closed the connection.')\ + from original