diff options
author | Andrew Svetlov <andrew.svetlov@gmail.com> | 2019-05-27 13:28:34 (GMT) |
---|---|---|
committer | Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> | 2019-05-27 13:28:34 (GMT) |
commit | 1f39c28e489cca0397fc4c3675d13569318122ac (patch) | |
tree | 60e976746b5353b636d9db95e8a8728c4a1f3f6c | |
parent | ff6b2e66b19a26b4c2ab57e62e1ab9f3d94dd76a (diff) | |
download | cpython-1f39c28e489cca0397fc4c3675d13569318122ac.zip cpython-1f39c28e489cca0397fc4c3675d13569318122ac.tar.gz cpython-1f39c28e489cca0397fc4c3675d13569318122ac.tar.bz2 |
bpo-37035: Don't log OSError (GH-13548)
https://bugs.python.org/issue37035
-rw-r--r-- | Lib/asyncio/base_events.py | 7 | ||||
-rw-r--r-- | Lib/asyncio/proactor_events.py | 2 | ||||
-rw-r--r-- | Lib/asyncio/selector_events.py | 2 | ||||
-rw-r--r-- | Lib/asyncio/sslproto.py | 2 | ||||
-rw-r--r-- | Lib/asyncio/unix_events.py | 2 | ||||
-rw-r--r-- | Lib/test/test_asyncio/test_selector_events.py | 27 | ||||
-rw-r--r-- | Lib/test/test_asyncio/test_unix_events.py | 6 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Library/2019-05-24-18-16-07.bpo-37035.HFbJVT.rst | 5 |
8 files changed, 35 insertions, 18 deletions
diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index 63b072b..ce4f190 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -59,13 +59,6 @@ _MIN_SCHEDULED_TIMER_HANDLES = 100 # before cleanup of cancelled handles is performed. _MIN_CANCELLED_TIMER_HANDLES_FRACTION = 0.5 -# Exceptions which must not call the exception handler in fatal error -# methods (_fatal_error()) -_FATAL_ERROR_IGNORE = (BrokenPipeError, - ConnectionResetError, ConnectionAbortedError) - -if ssl is not None: - _FATAL_ERROR_IGNORE = _FATAL_ERROR_IGNORE + (ssl.SSLCertVerificationError,) _HAS_IPv6 = hasattr(socket, 'AF_INET6') diff --git a/Lib/asyncio/proactor_events.py b/Lib/asyncio/proactor_events.py index 7dfe295..710f768 100644 --- a/Lib/asyncio/proactor_events.py +++ b/Lib/asyncio/proactor_events.py @@ -96,7 +96,7 @@ class _ProactorBasePipeTransport(transports._FlowControlMixin, def _fatal_error(self, exc, message='Fatal error on pipe transport'): try: - if isinstance(exc, base_events._FATAL_ERROR_IGNORE): + if isinstance(exc, OSError): if self._loop.get_debug(): logger.debug("%r: %s", self, message, exc_info=True) else: diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py index f5f43a9..44c380a 100644 --- a/Lib/asyncio/selector_events.py +++ b/Lib/asyncio/selector_events.py @@ -685,7 +685,7 @@ class _SelectorTransport(transports._FlowControlMixin, def _fatal_error(self, exc, message='Fatal error on transport'): # Should be called from exception handler only. - if isinstance(exc, base_events._FATAL_ERROR_IGNORE): + if isinstance(exc, OSError): if self._loop.get_debug(): logger.debug("%r: %s", self, message, exc_info=True) else: diff --git a/Lib/asyncio/sslproto.py b/Lib/asyncio/sslproto.py index 8546985..3eca6b4 100644 --- a/Lib/asyncio/sslproto.py +++ b/Lib/asyncio/sslproto.py @@ -707,7 +707,7 @@ class SSLProtocol(protocols.Protocol): self._fatal_error(exc, 'Fatal error on SSL transport') def _fatal_error(self, exc, message='Fatal error on transport'): - if isinstance(exc, base_events._FATAL_ERROR_IGNORE): + if isinstance(exc, OSError): if self._loop.get_debug(): logger.debug("%r: %s", self, message, exc_info=True) else: diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py index 81d10b1..28128d2 100644 --- a/Lib/asyncio/unix_events.py +++ b/Lib/asyncio/unix_events.py @@ -724,7 +724,7 @@ class _UnixWritePipeTransport(transports._FlowControlMixin, def _fatal_error(self, exc, message='Fatal error on pipe transport'): # should be called by exception handler only - if isinstance(exc, base_events._FATAL_ERROR_IGNORE): + if isinstance(exc, OSError): if self._loop.get_debug(): logger.debug("%r: %s", self, message, exc_info=True) else: diff --git a/Lib/test/test_asyncio/test_selector_events.py b/Lib/test/test_asyncio/test_selector_events.py index bf721b0..2e52e9d 100644 --- a/Lib/test/test_asyncio/test_selector_events.py +++ b/Lib/test/test_asyncio/test_selector_events.py @@ -448,10 +448,23 @@ class SelectorTransportTests(test_utils.TestCase): tr._force_close = mock.Mock() tr._fatal_error(exc) + m_exc.assert_not_called() + + tr._force_close.assert_called_with(exc) + + @mock.patch('asyncio.log.logger.error') + def test_fatal_error_custom_exception(self, m_exc): + class MyError(Exception): + pass + exc = MyError() + tr = self.create_transport() + tr._force_close = mock.Mock() + tr._fatal_error(exc) + m_exc.assert_called_with( test_utils.MockPattern( 'Fatal error on transport\nprotocol:.*\ntransport:.*'), - exc_info=(OSError, MOCK_ANY, MOCK_ANY)) + exc_info=(MyError, MOCK_ANY, MOCK_ANY)) tr._force_close.assert_called_with(exc) @@ -1338,10 +1351,20 @@ class SelectorDatagramTransportTests(test_utils.TestCase): err = ConnectionRefusedError() transport._fatal_error(err) self.assertFalse(self.protocol.error_received.called) + m_exc.assert_not_called() + + @mock.patch('asyncio.base_events.logger.error') + def test_fatal_error_connected_custom_error(self, m_exc): + class MyException(Exception): + pass + transport = self.datagram_transport(address=('0.0.0.0', 1)) + err = MyException() + transport._fatal_error(err) + self.assertFalse(self.protocol.error_received.called) m_exc.assert_called_with( test_utils.MockPattern( 'Fatal error on transport\nprotocol:.*\ntransport:.*'), - exc_info=(ConnectionRefusedError, MOCK_ANY, MOCK_ANY)) + exc_info=(MyException, MOCK_ANY, MOCK_ANY)) if __name__ == '__main__': diff --git a/Lib/test/test_asyncio/test_unix_events.py b/Lib/test/test_asyncio/test_unix_events.py index 31e7100..ac84304 100644 --- a/Lib/test/test_asyncio/test_unix_events.py +++ b/Lib/test/test_asyncio/test_unix_events.py @@ -977,11 +977,7 @@ class UnixWritePipeTransportTests(test_utils.TestCase): self.assertFalse(self.loop.readers) self.assertEqual(bytearray(), tr._buffer) self.assertTrue(tr.is_closing()) - m_logexc.assert_called_with( - test_utils.MockPattern( - 'Fatal write error on pipe transport' - '\nprotocol:.*\ntransport:.*'), - exc_info=(OSError, MOCK_ANY, MOCK_ANY)) + m_logexc.assert_not_called() self.assertEqual(1, tr._conn_lost) test_utils.run_briefly(self.loop) self.protocol.connection_lost.assert_called_with(err) diff --git a/Misc/NEWS.d/next/Library/2019-05-24-18-16-07.bpo-37035.HFbJVT.rst b/Misc/NEWS.d/next/Library/2019-05-24-18-16-07.bpo-37035.HFbJVT.rst new file mode 100644 index 0000000..004ec2d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-24-18-16-07.bpo-37035.HFbJVT.rst @@ -0,0 +1,5 @@ +Don't log OSError based exceptions if a fatal error has occurred in asyncio +transport. Peer can generate almost any OSError, user cannot avoid these exceptions +by fixing own code. +Errors are still propagated to user code, it's just logging them +is pointless and pollute asyncio logs. |