From: Ben Darnell Date: Tue, 9 Dec 2014 04:30:17 +0000 (-0500) Subject: Merge branch 'master' into log_future X-Git-Tag: v4.1.0b1~30^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6613adf659b2190639bcfcdb097c1bab03b5a39e;p=thirdparty%2Ftornado.git Merge branch 'master' into log_future --- 6613adf659b2190639bcfcdb097c1bab03b5a39e diff --cc tornado/concurrent.py index b03e9d254,6bab5d2e0..d32f2c6ec --- a/tornado/concurrent.py +++ b/tornado/concurrent.py @@@ -25,12 -25,11 +25,13 @@@ module from __future__ import absolute_import, division, print_function, with_statement import functools +import traceback import sys +from tornado.log import app_log from tornado.stack_context import ExceptionStackContext, wrap from tornado.util import raise_exc_info, ArgReplacer + from tornado.log import app_log try: from concurrent import futures @@@ -288,30 -174,12 +289,33 @@@ class Future(object) def _set_done(self): self._done = True for cb in self._callbacks: - # TODO: error handling - cb(self) + try: + cb(self) + except Exception: + app_log.exception('exception calling callback %r for %r', + cb, self) self._callbacks = None + + # On Python 3.3 or older, objects with a destructor part of a reference + # cycle are never destroyed. It's not more the case on Python 3.4 thanks to + # the PEP 442. + if _PY34: + def __del__(self): + if not self._log_traceback: + # set_exception() was not called, or result() or exception() + # has consumed the exception + return + + exc = self._exception + tb = traceback.format_exception(exc.__class__, exc, + exc.__traceback__) + + msg = '%s exception was never retrieved: %s' % \ + (self.__class__.__name__, ''.join(tb).rstrip()) + + # HACK: should probably call something + app_log.error(msg) + TracebackFuture = Future