From: Ben Darnell Date: Tue, 19 Feb 2013 04:03:19 +0000 (-0500) Subject: Exceptions in a @return_future function go to both the caller and the Future. X-Git-Tag: v3.0.0~103 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f695e4e471e503641390a372e5ddf6a67abb3c97;p=thirdparty%2Ftornado.git Exceptions in a @return_future function go to both the caller and the Future. Add a test for the UnboundLocal error seen here and remove the no-longer-needed initialization. I'm not 100% sure we want to do both (due to the risk of callback-doubling), but the old way where the caller saw one error and the future resolved to a different error was clearly incorrect, and leaving the future unresolved doesn't seem right either. --- diff --git a/tornado/concurrent.py b/tornado/concurrent.py index 2ca05901d..66cea30be 100644 --- a/tornado/concurrent.py +++ b/tornado/concurrent.py @@ -156,11 +156,11 @@ def return_future(f): return True exc_info = None with ExceptionStackContext(handle_error): - result = None try: result = f(*args, **kwargs) except: exc_info = sys.exc_info() + raise assert result is None, ("@return_future should not be used with " "functions that return values") if exc_info is not None: diff --git a/tornado/test/concurrent_test.py b/tornado/test/concurrent_test.py index 3419bbfd3..f0add7794 100644 --- a/tornado/test/concurrent_test.py +++ b/tornado/test/concurrent_test.py @@ -46,7 +46,12 @@ class ReturnFutureTest(AsyncTestCase): def test_immediate_failure(self): with self.assertRaises(ZeroDivisionError): + # The caller sees the error just like a normal function. self.immediate_failure(callback=self.stop) + # The callback is also run, with a future that contains the error. + future = self.wait() + with self.assertRaises(ZeroDivisionError): + future.result() def test_callback_kw(self): future = self.sync_future(callback=self.stop)