[Python-checkins] cpython (3.4): asyncio, Tulip issue 139: Improve error messages on "fatal errors"

larry.hastings python-checkins at python.org
Mon Mar 17 07:32:09 CET 2014


http://hg.python.org/cpython/rev/e93a36a678da
changeset: 89731:e93a36a678da
branch: 3.4
user: Victor Stinner <victor.stinner at gmail.com>
date: Wed Feb 19 01:40:41 2014 +0100
summary:
 asyncio, Tulip issue 139: Improve error messages on "fatal errors"
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").
files:
 Lib/asyncio/proactor_events.py | 10 +-
 Lib/asyncio/selector_events.py | 22 +++--
 Lib/asyncio/unix_events.py | 14 +-
 Lib/test/test_asyncio/test_proactor_events.py | 12 ++-
 Lib/test/test_asyncio/test_selector_events.py | 36 +++++++--
 Lib/test/test_asyncio/test_unix_events.py | 8 +-
 6 files changed, 64 insertions(+), 38 deletions(-)
diff --git a/Lib/asyncio/proactor_events.py b/Lib/asyncio/proactor_events.py
--- a/Lib/asyncio/proactor_events.py
+++ b/Lib/asyncio/proactor_events.py
@@ -53,10 +53,10 @@
 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 @@
 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 @@
 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
diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py
--- a/Lib/asyncio/selector_events.py
+++ b/Lib/asyncio/selector_events.py
@@ -377,11 +377,11 @@
 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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 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.
diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py
--- a/Lib/asyncio/unix_events.py
+++ b/Lib/asyncio/unix_events.py
@@ -271,7 +271,7 @@
 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 @@
 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 @@
 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 @@
 # 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 @@
 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,
diff --git a/Lib/test/test_asyncio/test_proactor_events.py b/Lib/test/test_asyncio/test_proactor_events.py
--- a/Lib/test/test_asyncio/test_proactor_events.py
+++ b/Lib/test/test_asyncio/test_proactor_events.py
@@ -69,7 +69,9 @@
 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 @@
 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 @@
 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')
diff --git a/Lib/test/test_asyncio/test_selector_events.py b/Lib/test/test_asyncio/test_selector_events.py
--- a/Lib/test/test_asyncio/test_selector_events.py
+++ b/Lib/test/test_asyncio/test_selector_events.py
@@ -655,7 +655,7 @@
 
 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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 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))
 
 
diff --git a/Lib/test/test_asyncio/test_unix_events.py b/Lib/test/test_asyncio/test_unix_events.py
--- a/Lib/test/test_asyncio/test_unix_events.py
+++ b/Lib/test/test_asyncio/test_unix_events.py
@@ -365,7 +365,7 @@
 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 @@
 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 @@
 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)
-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /