From c6521eba719e70023be0f395476f0cfe0b08f004 Mon Sep 17 00:00:00 2001 From: Ross McFarland Date: Thu, 27 Oct 2011 19:38:13 -0700 Subject: [PATCH] throw exceptions with original stack traces - use exc_info and 3 arg raise - still log original call stack trace on errors --- asynchttp/__init__.py | 21 +++++++++++++-------- tests/test_promise.py | 4 +++- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/asynchttp/__init__.py b/asynchttp/__init__.py index 5f45b81..24134ba 100644 --- a/asynchttp/__init__.py +++ b/asynchttp/__init__.py @@ -10,6 +10,7 @@ __credits__ = '''Ross McFarland''' from Queue import Queue +from sys import exc_info from threading import Event, Thread from traceback import extract_stack, format_list import httplib2 @@ -35,12 +36,14 @@ def __init__(self, callback=None): self.__stack = extract_stack()[:-2] logger.debug('%s.__init__', self) - def fulfill(self, response, content, exception=None): + def fulfill(self, response, content, caught_exc_info=None): try: logger.debug('%s.fullfill', self) self.response = response self.content = content - self.exception = exception + self.caught_exc_info = caught_exc_info + if caught_exc_info: + self.exception = caught_exc_info[1] if self.__callback is not None: logger.debug('%s.fullfill invoking callback', self) try: @@ -49,8 +52,9 @@ def fulfill(self, response, content, exception=None): logger.exception('%s.fullfill callback threw an exception,' ' %s, original invocation:\n%s', self, e, ''.join(format_list(self.__stack))) - if self.exception is None: - self.exception = e + if self.caught_exc_info is None: + self.caught_exc_info = exc_info() + self.exception = self.caught_exc_info[1] finally: # set flag no matter what else things can hang waiting for a # response @@ -62,11 +66,12 @@ def done(self): def wait(self): logger.debug('%s.wait', self) self.__flag.wait() - if self.exception: + if self.caught_exc_info: logger.info('%s.wait: raising exception, %s, original invocation:' - '\n%s', self, self.exception, + '\n%s', self, self.caught_exc_info[1], ''.join(format_list(self.__stack))) - raise self.exception + raise self.caught_exc_info[0], self.caught_exc_info[1], \ + self.caught_exc_info[2] def get_response(self): self.wait() @@ -164,7 +169,7 @@ def run(self): promise.fulfill(response, content) except Exception, e: logger.warn('%s.run: request raised exception: %s', self, e) - promise.fulfill(None, None, e) + promise.fulfill(None, None, exc_info()) logger.debug('%s.run: done', self) self.__http._remove_worker(self) diff --git a/tests/test_promise.py b/tests/test_promise.py index 2c7126a..f3084a8 100644 --- a/tests/test_promise.py +++ b/tests/test_promise.py @@ -6,6 +6,7 @@ from asynchttp import Promise from datetime import datetime, timedelta +from sys import exc_info from threading import Thread from time import sleep from unittest2 import TestCase @@ -84,7 +85,8 @@ def failing_callback(promise): class HooException(Exception): pass - promise.fulfill(43, 44, HooException('blah!')) + e = HooException('blah!') + promise.fulfill(43, 44, (e.__class__, e, None)) self.assertIsInstance(promise.exception, HooException) self.assertRaises(HooException, promise.get_response) self.assertRaises(HooException, promise.get_content)