From 27f508f4e98518119c310742f8e96d127bbeff82 Mon Sep 17 00:00:00 2001 From: Martin Sucha Date: Fri, 7 Aug 2015 15:42:48 +0200 Subject: [PATCH] Fix error handling in read_until_close When a callback is supplied, the future is not created. Make sure it is used only if it was initialized, otherwise we lose the error that was originally raised. --- tornado/iostream.py | 3 ++- tornado/test/iostream_test.py | 12 ++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/tornado/iostream.py b/tornado/iostream.py index e17786ae1..c5d3e2c9d 100644 --- a/tornado/iostream.py +++ b/tornado/iostream.py @@ -352,7 +352,8 @@ class BaseIOStream(object): try: self._try_inline_read() except: - future.add_done_callback(lambda f: f.exception()) + if future is not None: + future.add_done_callback(lambda f: f.exception()) raise return future diff --git a/tornado/test/iostream_test.py b/tornado/test/iostream_test.py index bc12c8189..060f7a454 100644 --- a/tornado/test/iostream_test.py +++ b/tornado/test/iostream_test.py @@ -457,6 +457,18 @@ class TestIOStreamMixin(object): server.close() client.close() + @unittest.skipIf(mock is None, 'mock package not present') + def test_read_until_close_with_error(self): + server, client = self.make_iostream_pair() + try: + with mock.patch('tornado.iostream.BaseIOStream._try_inline_read', + side_effect=IOError('boom')): + with self.assertRaisesRegexp(IOError, 'boom'): + client.read_until_close(self.stop) + finally: + server.close() + client.close() + def test_streaming_read_until_close_after_close(self): # Same as the preceding test but with a streaming_callback. # All data should go through the streaming callback, -- 2.47.2