]> granicus.if.org Git - python/commitdiff
asyncio, Tulip issue 139: Improve error messages on "fatal errors"
authorVictor Stinner <victor.stinner@gmail.com>
Wed, 19 Feb 2014 00:40:41 +0000 (01:40 +0100)
committerVictor Stinner <victor.stinner@gmail.com>
Wed, 19 Feb 2014 00:40:41 +0000 (01:40 +0100)
Mention if the error was caused by a read or a write, and be more specific on
the object (ex: "pipe transport" instead of "transport").

Lib/asyncio/proactor_events.py
Lib/asyncio/selector_events.py
Lib/asyncio/unix_events.py
Lib/test/test_asyncio/test_proactor_events.py
Lib/test/test_asyncio/test_selector_events.py
Lib/test/test_asyncio/test_unix_events.py

index d72f9274a8342f51f9a7ac298539376c97a52b9f..f45cd9c680d9a9600f8e4365c83ed02e9d377221 100644 (file)
@@ -53,10 +53,10 @@ class _ProactorBasePipeTransport(transports._FlowControlMixin,
         if self._read_fut is not None:
             self._read_fut.cancel()
 
-    def _fatal_error(self, exc):
+    def _fatal_error(self, exc, message='Fatal error on pipe transport'):
         if not isinstance(exc, (BrokenPipeError, ConnectionResetError)):
             self._loop.call_exception_handler({
-                'message': 'Fatal transport error',
+                'message': message,
                 'exception': exc,
                 'transport': self,
                 'protocol': self._protocol,
@@ -151,11 +151,11 @@ class _ProactorReadPipeTransport(_ProactorBasePipeTransport,
             self._read_fut = self._loop._proactor.recv(self._sock, 4096)
         except ConnectionAbortedError as exc:
             if not self._closing:
-                self._fatal_error(exc)
+                self._fatal_error(exc, 'Fatal read error on pipe transport')
         except ConnectionResetError as exc:
             self._force_close(exc)
         except OSError as exc:
-            self._fatal_error(exc)
+            self._fatal_error(exc, 'Fatal read error on pipe transport')
         except futures.CancelledError:
             if not self._closing:
                 raise
@@ -246,7 +246,7 @@ class _ProactorBaseWritePipeTransport(_ProactorBasePipeTransport,
         except ConnectionResetError as exc:
             self._force_close(exc)
         except OSError as exc:
-            self._fatal_error(exc)
+            self._fatal_error(exc, 'Fatal write error on pipe transport')
 
     def can_write_eof(self):
         return True
index 869d66e0c8f5c0e6967f43b6a91887c0a88f79b5..c142356f721b7f7ed9b9367dab8d4f2077e8b3d1 100644 (file)
@@ -377,11 +377,11 @@ class _SelectorTransport(transports._FlowControlMixin,
             self._conn_lost += 1
             self._loop.call_soon(self._call_connection_lost, None)
 
-    def _fatal_error(self, exc):
+    def _fatal_error(self, exc, message='Fatal error on transport'):
         # Should be called from exception handler only.
         if not isinstance(exc, (BrokenPipeError, ConnectionResetError)):
             self._loop.call_exception_handler({
-                'message': 'Fatal transport error',
+                'message': message,
                 'exception': exc,
                 'transport': self,
                 'protocol': self._protocol,
@@ -452,7 +452,7 @@ class _SelectorSocketTransport(_SelectorTransport):
         except (BlockingIOError, InterruptedError):
             pass
         except Exception as exc:
-            self._fatal_error(exc)
+            self._fatal_error(exc, 'Fatal read error on socket transport')
         else:
             if data:
                 self._protocol.data_received(data)
@@ -488,7 +488,7 @@ class _SelectorSocketTransport(_SelectorTransport):
             except (BlockingIOError, InterruptedError):
                 pass
             except Exception as exc:
-                self._fatal_error(exc)
+                self._fatal_error(exc, 'Fatal write error on socket transport')
                 return
             else:
                 data = data[n:]
@@ -511,7 +511,7 @@ class _SelectorSocketTransport(_SelectorTransport):
         except Exception as exc:
             self._loop.remove_writer(self._sock_fd)
             self._buffer.clear()
-            self._fatal_error(exc)
+            self._fatal_error(exc, 'Fatal write error on socket transport')
         else:
             if n:
                 del self._buffer[:n]
@@ -678,7 +678,7 @@ class _SelectorSslTransport(_SelectorTransport):
             self._loop.remove_reader(self._sock_fd)
             self._loop.add_writer(self._sock_fd, self._write_ready)
         except Exception as exc:
-            self._fatal_error(exc)
+            self._fatal_error(exc, 'Fatal read error on SSL transport')
         else:
             if data:
                 self._protocol.data_received(data)
@@ -712,7 +712,7 @@ class _SelectorSslTransport(_SelectorTransport):
             except Exception as exc:
                 self._loop.remove_writer(self._sock_fd)
                 self._buffer.clear()
-                self._fatal_error(exc)
+                self._fatal_error(exc, 'Fatal write error on SSL transport')
                 return
 
             if n:
@@ -770,7 +770,7 @@ class _SelectorDatagramTransport(_SelectorTransport):
         except OSError as exc:
             self._protocol.error_received(exc)
         except Exception as exc:
-            self._fatal_error(exc)
+            self._fatal_error(exc, 'Fatal read error on datagram transport')
         else:
             self._protocol.datagram_received(data, addr)
 
@@ -805,7 +805,8 @@ class _SelectorDatagramTransport(_SelectorTransport):
                 self._protocol.error_received(exc)
                 return
             except Exception as exc:
-                self._fatal_error(exc)
+                self._fatal_error(exc,
+                                  'Fatal write error on datagram transport')
                 return
 
         # Ensure that what we buffer is immutable.
@@ -827,7 +828,8 @@ class _SelectorDatagramTransport(_SelectorTransport):
                 self._protocol.error_received(exc)
                 return
             except Exception as exc:
-                self._fatal_error(exc)
+                self._fatal_error(exc,
+                                  'Fatal write error on datagram transport')
                 return
 
         self._maybe_resume_protocol()  # May append to buffer.
index 748452c588618267214713821ab90fdc2f9793cb..3a2fd18b2dff9650488bf4c4d10f22feca3eb958 100644 (file)
@@ -271,7 +271,7 @@ class _UnixReadPipeTransport(transports.ReadTransport):
         except (BlockingIOError, InterruptedError):
             pass
         except OSError as exc:
-            self._fatal_error(exc)
+            self._fatal_error(exc, 'Fatal read error on pipe transport')
         else:
             if data:
                 self._protocol.data_received(data)
@@ -291,11 +291,11 @@ class _UnixReadPipeTransport(transports.ReadTransport):
         if not self._closing:
             self._close(None)
 
-    def _fatal_error(self, exc):
+    def _fatal_error(self, exc, message='Fatal error on pipe transport'):
         # should be called by exception handler only
         if not (isinstance(exc, OSError) and exc.errno == errno.EIO):
             self._loop.call_exception_handler({
-                'message': 'Fatal transport error',
+                'message': message,
                 'exception': exc,
                 'transport': self,
                 'protocol': self._protocol,
@@ -381,7 +381,7 @@ class _UnixWritePipeTransport(transports._FlowControlMixin,
                 n = 0
             except Exception as exc:
                 self._conn_lost += 1
-                self._fatal_error(exc)
+                self._fatal_error(exc, 'Fatal write error on pipe transport')
                 return
             if n == len(data):
                 return
@@ -406,7 +406,7 @@ class _UnixWritePipeTransport(transports._FlowControlMixin,
             # Remove writer here, _fatal_error() doesn't it
             # because _buffer is empty.
             self._loop.remove_writer(self._fileno)
-            self._fatal_error(exc)
+            self._fatal_error(exc, 'Fatal write error on pipe transport')
         else:
             if n == len(data):
                 self._loop.remove_writer(self._fileno)
@@ -443,11 +443,11 @@ class _UnixWritePipeTransport(transports._FlowControlMixin,
     def abort(self):
         self._close(None)
 
-    def _fatal_error(self, exc):
+    def _fatal_error(self, exc, message='Fatal error on pipe transport'):
         # should be called by exception handler only
         if not isinstance(exc, (BrokenPipeError, ConnectionResetError)):
             self._loop.call_exception_handler({
-                'message': 'Fatal transport error',
+                'message': message,
                 'exception': exc,
                 'transport': self,
                 'protocol': self._protocol,
index 816c9732b092c2546b99d67f410b74efb3f69146..08920690b83a4bd4a09b1400147b27b22bf286b6 100644 (file)
@@ -69,7 +69,9 @@ class ProactorSocketTransportTests(unittest.TestCase):
         tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol)
         tr._fatal_error = unittest.mock.Mock()
         tr._loop_reading()
-        tr._fatal_error.assert_called_with(err)
+        tr._fatal_error.assert_called_with(
+                            err,
+                            'Fatal read error on pipe transport')
 
     def test_loop_reading_aborted_closing(self):
         self.loop._proactor.recv.side_effect = ConnectionAbortedError()
@@ -105,7 +107,9 @@ class ProactorSocketTransportTests(unittest.TestCase):
         tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol)
         tr._fatal_error = unittest.mock.Mock()
         tr._loop_reading()
-        tr._fatal_error.assert_called_with(err)
+        tr._fatal_error.assert_called_with(
+                            err,
+                            'Fatal read error on pipe transport')
 
     def test_write(self):
         tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol)
@@ -142,7 +146,9 @@ class ProactorSocketTransportTests(unittest.TestCase):
         tr._fatal_error = unittest.mock.Mock()
         tr._buffer = [b'da', b'ta']
         tr._loop_writing()
-        tr._fatal_error.assert_called_with(err)
+        tr._fatal_error.assert_called_with(
+                            err,
+                            'Fatal write error on pipe transport')
         tr._conn_lost = 1
 
         tr.write(b'data')
index 04b057805937ce39ab9e6fa4c595f188a86f8823..247df9e01c73a5f5a4b6340482a58c182e19ff30 100644 (file)
@@ -655,7 +655,7 @@ class SelectorTransportTests(unittest.TestCase):
 
         m_exc.assert_called_with(
             test_utils.MockPattern(
-                'Fatal transport error\nprotocol:.*\ntransport:.*'),
+                'Fatal error on transport\nprotocol:.*\ntransport:.*'),
             exc_info=(OSError, MOCK_ANY, MOCK_ANY))
 
         tr._force_close.assert_called_with(exc)
@@ -785,7 +785,9 @@ class SelectorSocketTransportTests(unittest.TestCase):
         transport._fatal_error = unittest.mock.Mock()
         transport._read_ready()
 
-        transport._fatal_error.assert_called_with(err)
+        transport._fatal_error.assert_called_with(
+                                   err,
+                                   'Fatal read error on socket transport')
 
     def test_write(self):
         data = b'data'
@@ -898,7 +900,9 @@ class SelectorSocketTransportTests(unittest.TestCase):
             self.loop, self.sock, self.protocol)
         transport._fatal_error = unittest.mock.Mock()
         transport.write(data)
-        transport._fatal_error.assert_called_with(err)
+        transport._fatal_error.assert_called_with(
+                                   err,
+                                   'Fatal write error on socket transport')
         transport._conn_lost = 1
 
         self.sock.reset_mock()
@@ -1001,7 +1005,9 @@ class SelectorSocketTransportTests(unittest.TestCase):
         transport._fatal_error = unittest.mock.Mock()
         transport._buffer.extend(b'data')
         transport._write_ready()
-        transport._fatal_error.assert_called_with(err)
+        transport._fatal_error.assert_called_with(
+                                   err,
+                                   'Fatal write error on socket transport')
 
     @unittest.mock.patch('asyncio.base_events.logger')
     def test_write_ready_exception_and_close(self, m_log):
@@ -1237,7 +1243,9 @@ class SelectorSslTransportTests(unittest.TestCase):
         transport = self._make_one()
         transport._fatal_error = unittest.mock.Mock()
         transport._read_ready()
-        transport._fatal_error.assert_called_with(err)
+        transport._fatal_error.assert_called_with(
+                                   err,
+                                   'Fatal read error on SSL transport')
 
     def test_write_ready_send(self):
         self.sslsock.send.return_value = 4
@@ -1319,7 +1327,9 @@ class SelectorSslTransportTests(unittest.TestCase):
         transport._buffer = list_to_buffer([b'data'])
         transport._fatal_error = unittest.mock.Mock()
         transport._write_ready()
-        transport._fatal_error.assert_called_with(err)
+        transport._fatal_error.assert_called_with(
+                                   err,
+                                   'Fatal write error on SSL transport')
         self.assertEqual(list_to_buffer(), transport._buffer)
 
     def test_write_ready_read_wants_write(self):
@@ -1407,7 +1417,9 @@ class SelectorDatagramTransportTests(unittest.TestCase):
         transport._fatal_error = unittest.mock.Mock()
         transport._read_ready()
 
-        transport._fatal_error.assert_called_with(err)
+        transport._fatal_error.assert_called_with(
+                                   err,
+                                   'Fatal read error on datagram transport')
 
     def test_read_ready_oserr(self):
         transport = _SelectorDatagramTransport(
@@ -1517,7 +1529,9 @@ class SelectorDatagramTransportTests(unittest.TestCase):
         transport.sendto(data, ())
 
         self.assertTrue(transport._fatal_error.called)
-        transport._fatal_error.assert_called_with(err)
+        transport._fatal_error.assert_called_with(
+                                   err,
+                                   'Fatal write error on datagram transport')
         transport._conn_lost = 1
 
         transport._address = ('123',)
@@ -1633,7 +1647,9 @@ class SelectorDatagramTransportTests(unittest.TestCase):
         transport._buffer.append((b'data', ()))
         transport._sendto_ready()
 
-        transport._fatal_error.assert_called_with(err)
+        transport._fatal_error.assert_called_with(
+                                   err,
+                                   'Fatal write error on datagram transport')
 
     def test_sendto_ready_error_received(self):
         self.sock.sendto.side_effect = ConnectionRefusedError
@@ -1667,7 +1683,7 @@ class SelectorDatagramTransportTests(unittest.TestCase):
         self.assertFalse(self.protocol.error_received.called)
         m_exc.assert_called_with(
             test_utils.MockPattern(
-                'Fatal transport error\nprotocol:.*\ntransport:.*'),
+                'Fatal error on transport\nprotocol:.*\ntransport:.*'),
             exc_info=(ConnectionRefusedError, MOCK_ANY, MOCK_ANY))
 
 
index e93307979b8545041735dd8259c0fcf35412ab57..9866e33affc3dbc6eaae81b4f7251ca8f3b770f7 100644 (file)
@@ -365,7 +365,7 @@ class UnixReadPipeTransportTests(unittest.TestCase):
         tr._close.assert_called_with(err)
         m_logexc.assert_called_with(
             test_utils.MockPattern(
-                'Fatal transport error\nprotocol:.*\ntransport:.*'),
+                'Fatal read error on pipe transport\nprotocol:.*\ntransport:.*'),
             exc_info=(OSError, MOCK_ANY, MOCK_ANY))
 
     @unittest.mock.patch('os.read')
@@ -558,7 +558,9 @@ class UnixWritePipeTransportTests(unittest.TestCase):
         m_write.assert_called_with(5, b'data')
         self.assertFalse(self.loop.writers)
         self.assertEqual([], tr._buffer)
-        tr._fatal_error.assert_called_with(err)
+        tr._fatal_error.assert_called_with(
+                            err,
+                            'Fatal write error on pipe transport')
         self.assertEqual(1, tr._conn_lost)
 
         tr.write(b'data')
@@ -660,7 +662,7 @@ class UnixWritePipeTransportTests(unittest.TestCase):
         self.assertTrue(tr._closing)
         m_logexc.assert_called_with(
             test_utils.MockPattern(
-                'Fatal transport error\nprotocol:.*\ntransport:.*'),
+                'Fatal write error on pipe transport\nprotocol:.*\ntransport:.*'),
             exc_info=(OSError, MOCK_ANY, MOCK_ANY))
         self.assertEqual(1, tr._conn_lost)
         test_utils.run_briefly(self.loop)