def process(self): try: known_type = INT_DEFAULT_REPLY_TYPE input_data = self._read() if not input_data: return False method = input_data['m'] meth = getattr(SolardIface, method) is_stream = input_data.get('s', False) logger.debug("Going to run %r", method) if is_stream: res = meth(self.ctx, self._read_stream, *input_data.get('args', ()), **input_data.get('kwargs', {})) else: res = meth(self.ctx, *input_data.get('args', ()), **input_data.get('kwargs', {})) if isinstance(res, GeneratorType): known_type = INT_GENERATOR_REPLY_TYPE try: for curr in res: self._wrote = False self._write_ok_gen(curr) except: raise finally: try: self._wrote = False self._write_gen_end() except Exception: # ignore if eng gen couldn't be send pass self._wrote = True else: # if not input_data.get('empty_ok_resp', False): self._write_ok(res) except ReadFailure: return False except Exception as ex: if self._wrote: if known_type == INT_GENERATOR_REPLY_TYPE: errno_ = getattr(ex, 'errno', None) if errno_ in (errno.EPIPE, errno.ECONNRESET): logger.debug( "Client disconnected during generator based reply") else: logger.debug("Error during generator based reply") raise else: logger.error("Already wrote data, but got exception") raise else: logger.exception("Got exception") self.handle_exception() return True
def handle_exception(self): exc_type, exc_value, exc_traceback = sys.exc_info() tb = traceback.format_exception(exc_type, exc_value, exc_traceback) reason = str(exc_value) if not reason: reason = exc_type.__name__ try: self._write_failure(exc_type.__name__, reason, tb) except: logger.warn("Failure when sending error response") raise finally: logger.exception("Got exception")