# HG changeset patch # User Atul Varma # Date 1240202746 25200 # Node ID 69efb6cdc12768975570f27887b62b0436739f92 # Parent 7b652e2ac62e79154b53db8a6de5aae391ae28a7 Added some error-handling code, though the channel code is raising exceptions in it at the moment I think. diff -r 7b652e2ac62e -r 69efb6cdc127 cosocket.py --- a/cosocket.py Sun Apr 19 20:29:17 2009 -0700 +++ b/cosocket.py Sun Apr 19 21:45:46 2009 -0700 @@ -5,6 +5,7 @@ import asyncore import asynchat import types +import traceback class _AsyncChatCoroutineDispatcher(asynchat.async_chat): def __init__(self, coroutine, conn = None): @@ -16,15 +17,25 @@ if conn: self.return_from_yield() - def return_from_yield(self, message = None): + def return_from_yield(self, message = None, exception = None): try: - instruction = self.__coroutine.send(message) + if exception: + instruction = self.__coroutine.throw(exception) + else: + instruction = self.__coroutine.send(message) except StopIteration: if self.__coroutine_stack: self.__coroutine = self.__coroutine_stack.pop() self.return_from_yield() else: - self.close() + self.__coroutine = None + self.handle_close() + except Exception, e: + if self.__coroutine_stack: + self.__coroutine = self.__coroutine_stack.pop() + self.return_from_yield(exception = e) + else: + self.handle_error() else: if type(instruction) == types.GeneratorType: self.__coroutine_stack.append(self.__coroutine) @@ -33,6 +44,29 @@ else: instruction.execute(self) + def __close_coroutine(self, coroutine): + try: + coroutine.close() + except Exception: + self.log_info(traceback.format_exc(), 'error') + + def handle_close(self): + if self.__coroutine: + # Pass an exception back into the coroutine to kick + # it out of whatever yielding state it's in. + self.__close_coroutine(self.__coroutine) + self.__coroutine = None + while self.__coroutine_stack: + self.__close_coroutine(self.__coroutine_stack.pop()) + self.close() + + def log_info(self, message, type='info'): + # TODO: Use the logging module here. + print '%s: %s' % (type, message) + + def handle_error(self): + self.log_info(traceback.format_exc(), 'error') + def handle_connect(self): self.return_from_yield()