From 7ae6c16b56663110d093a5c9c2adbe38a40c98c0 Mon Sep 17 00:00:00 2001 From: Nicholas Burlett Date: Tue, 21 May 2024 13:53:52 -0700 Subject: [PATCH] fix AbstractTransport repr socket error (#361) If AbstractTransport's self.sock is disconnected, then self.sock.getpeername() will raise an error in __repr__, which shows up in backtraces for other upstream errors. Fix this by catching socket.error in __repr__ and putting the error info in to the returned repr string. Fixes #361 --- amqp/transport.py | 5 ++++- t/unit/test_transport.py | 16 +++++++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/amqp/transport.py b/amqp/transport.py index c915977d..3d87e70e 100644 --- a/amqp/transport.py +++ b/amqp/transport.py @@ -116,7 +116,10 @@ def __init__(self, host, connect_timeout=None, def __repr__(self): if self.sock: src = f'{self.sock.getsockname()[0]}:{self.sock.getsockname()[1]}' - dst = f'{self.sock.getpeername()[0]}:{self.sock.getpeername()[1]}' + try: + dst = f'{self.sock.getpeername()[0]}:{self.sock.getpeername()[1]}' + except (socket.error) as e: + dst = f'ERROR: {e}' return f'<{type(self).__name__}: {src} -> {dst} at {id(self):#x}>' else: return f'<{type(self).__name__}: (disconnected) at {id(self):#x}>' diff --git a/t/unit/test_transport.py b/t/unit/test_transport.py index b00072c3..980a9ab7 100644 --- a/t/unit/test_transport.py +++ b/t/unit/test_transport.py @@ -59,7 +59,10 @@ def getsockname(self): return ('127.0.0.1', 1234) def getpeername(self): - return ('1.2.3.4', 5671) + if self.connected: + return ('1.2.3.4', 5671) + else: + raise socket.error TCP_KEEPIDLE = 4 @@ -237,6 +240,17 @@ def test_set_sockopt_opts_timeout(self): assert expected_sndtimeo == self.socket.getsockopt(socket.SOL_TCP, socket.SO_SNDTIMEO) + def test_transport_repr_issue_361(self): + "Regression test for https://github.com/celery/py-amqp/issues/361" + self.t = transport.Transport(self.host) + self.t.sock = MockSocket() + self.t.sock.connect(None) + assert '127.0.0.1:1234 -> 1.2.3.4:5671' in repr(self.t) + + self.t.sock.connected = False + self.t.sock.close() + assert '127.0.0.1:1234 -> ERROR:' in repr(self.t) + class test_AbstractTransport: class Transport(transport._AbstractTransport):