Skip to content

Commit 1f39c28

Browse files
asvetlovmiss-islington
authored andcommitted
1 parent ff6b2e6 commit 1f39c28

8 files changed

Lines changed: 35 additions & 18 deletions

File tree

Lib/asyncio/base_events.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,6 @@
5959
# before cleanup of cancelled handles is performed.
6060
_MIN_CANCELLED_TIMER_HANDLES_FRACTION = 0.5
6161

62-
# Exceptions which must not call the exception handler in fatal error
63-
# methods (_fatal_error())
64-
_FATAL_ERROR_IGNORE = (BrokenPipeError,
65-
ConnectionResetError, ConnectionAbortedError)
66-
67-
if ssl is not None:
68-
_FATAL_ERROR_IGNORE = _FATAL_ERROR_IGNORE + (ssl.SSLCertVerificationError,)
6962

7063
_HAS_IPv6 = hasattr(socket, 'AF_INET6')
7164

Lib/asyncio/proactor_events.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ def __del__(self, _warn=warnings.warn):
9696

9797
def _fatal_error(self, exc, message='Fatal error on pipe transport'):
9898
try:
99-
if isinstance(exc, base_events._FATAL_ERROR_IGNORE):
99+
if isinstance(exc, OSError):
100100
if self._loop.get_debug():
101101
logger.debug("%r: %s", self, message, exc_info=True)
102102
else:

Lib/asyncio/selector_events.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -685,7 +685,7 @@ def __del__(self, _warn=warnings.warn):
685685

686686
def _fatal_error(self, exc, message='Fatal error on transport'):
687687
# Should be called from exception handler only.
688-
if isinstance(exc, base_events._FATAL_ERROR_IGNORE):
688+
if isinstance(exc, OSError):
689689
if self._loop.get_debug():
690690
logger.debug("%r: %s", self, message, exc_info=True)
691691
else:

Lib/asyncio/sslproto.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -707,7 +707,7 @@ def _process_write_backlog(self):
707707
self._fatal_error(exc, 'Fatal error on SSL transport')
708708

709709
def _fatal_error(self, exc, message='Fatal error on transport'):
710-
if isinstance(exc, base_events._FATAL_ERROR_IGNORE):
710+
if isinstance(exc, OSError):
711711
if self._loop.get_debug():
712712
logger.debug("%r: %s", self, message, exc_info=True)
713713
else:

Lib/asyncio/unix_events.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -724,7 +724,7 @@ def abort(self):
724724

725725
def _fatal_error(self, exc, message='Fatal error on pipe transport'):
726726
# should be called by exception handler only
727-
if isinstance(exc, base_events._FATAL_ERROR_IGNORE):
727+
if isinstance(exc, OSError):
728728
if self._loop.get_debug():
729729
logger.debug("%r: %s", self, message, exc_info=True)
730730
else:

Lib/test/test_asyncio/test_selector_events.py

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -448,10 +448,23 @@ def test_fatal_error(self, m_exc):
448448
tr._force_close = mock.Mock()
449449
tr._fatal_error(exc)
450450

451+
m_exc.assert_not_called()
452+
453+
tr._force_close.assert_called_with(exc)
454+
455+
@mock.patch('asyncio.log.logger.error')
456+
def test_fatal_error_custom_exception(self, m_exc):
457+
class MyError(Exception):
458+
pass
459+
exc = MyError()
460+
tr = self.create_transport()
461+
tr._force_close = mock.Mock()
462+
tr._fatal_error(exc)
463+
451464
m_exc.assert_called_with(
452465
test_utils.MockPattern(
453466
'Fatal error on transport\nprotocol:.*\ntransport:.*'),
454-
exc_info=(OSError, MOCK_ANY, MOCK_ANY))
467+
exc_info=(MyError, MOCK_ANY, MOCK_ANY))
455468

456469
tr._force_close.assert_called_with(exc)
457470

@@ -1338,10 +1351,20 @@ def test_fatal_error_connected(self, m_exc):
13381351
err = ConnectionRefusedError()
13391352
transport._fatal_error(err)
13401353
self.assertFalse(self.protocol.error_received.called)
1354+
m_exc.assert_not_called()
1355+
1356+
@mock.patch('asyncio.base_events.logger.error')
1357+
def test_fatal_error_connected_custom_error(self, m_exc):
1358+
class MyException(Exception):
1359+
pass
1360+
transport = self.datagram_transport(address=('0.0.0.0', 1))
1361+
err = MyException()
1362+
transport._fatal_error(err)
1363+
self.assertFalse(self.protocol.error_received.called)
13411364
m_exc.assert_called_with(
13421365
test_utils.MockPattern(
13431366
'Fatal error on transport\nprotocol:.*\ntransport:.*'),
1344-
exc_info=(ConnectionRefusedError, MOCK_ANY, MOCK_ANY))
1367+
exc_info=(MyException, MOCK_ANY, MOCK_ANY))
13451368

13461369

13471370
if __name__ == '__main__':

Lib/test/test_asyncio/test_unix_events.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -977,11 +977,7 @@ def test__write_ready_err(self, m_write, m_logexc):
977977
self.assertFalse(self.loop.readers)
978978
self.assertEqual(bytearray(), tr._buffer)
979979
self.assertTrue(tr.is_closing())
980-
m_logexc.assert_called_with(
981-
test_utils.MockPattern(
982-
'Fatal write error on pipe transport'
983-
'\nprotocol:.*\ntransport:.*'),
984-
exc_info=(OSError, MOCK_ANY, MOCK_ANY))
980+
m_logexc.assert_not_called()
985981
self.assertEqual(1, tr._conn_lost)
986982
test_utils.run_briefly(self.loop)
987983
self.protocol.connection_lost.assert_called_with(err)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Don't log OSError based exceptions if a fatal error has occurred in asyncio
2+
transport. Peer can generate almost any OSError, user cannot avoid these exceptions
3+
by fixing own code.
4+
Errors are still propagated to user code, it's just logging them
5+
is pointless and pollute asyncio logs.

0 commit comments

Comments
 (0)