def _execution_control( self, fn: Callable, args: Optional[Sequence] = None, kwargs: Optional[Dict] = None, ) -> Any: """ Execute skill function in exception handling environment. Logs error, stop agent or propagate exception depends on policy defined. :param fn: function to call :param args: optional sequence of arguments to pass to function on call :param kwargs: optional dict of keyword arguments to pass to function on call :return: same as function """ execution_timeout = getattr(self.agent, "_execution_timeout", 0) try: with ExecTimeoutThreadGuard(execution_timeout): return fn(*(args or []), **(kwargs or {})) except TimeoutException: # pragma: nocover self.logger.warning( "`{}` was terminated as its execution exceeded the timeout of {} seconds. Please refactor your code!" .format(fn, execution_timeout)) except Exception as e: # pylint: disable=broad-except try: if self.agent.exception_handler(e, fn) is True: self._state.set(AgentLoopStates.error) raise except Exception as e: self._state.set(AgentLoopStates.error) self._exceptions.append(e) raise
def test_supervisor_not_started(): """Test that TestThreadGuard supervisor thread not started.""" timeout = 0.1 sleep_time = 0.5 exec_limiter = ExecTimeoutThreadGuard(timeout) with exec_limiter as exec_limit: assert not exec_limiter._future_guard_task TestThreadGuard.slow_function(sleep_time) assert not exec_limit.is_cancelled_by_timeout()
def _execution_control( self, fn: Callable, component: SkillComponent, args: Optional[Sequence] = None, kwargs: Optional[Dict] = None, ) -> Any: """ Execute skill function in exception handling environment. Logs error, stop agent or propagate excepion depends on policy defined. :param fn: function to call :param component: skill component function belongs to :param args: optional sequence of arguments to pass to function on call :param kwargs: optional dict of keyword arguments to pass to function on call :return: same as function """ # docstyle: ignore def log_exception(e, fn, component): logger.exception( f"<{e}> raised during `{fn}` call of `{component}`") try: with ExecTimeoutThreadGuard(self._execution_timeout): return fn(*(args or []), **(kwargs or {})) except TimeoutException: logger.warning( "`{}` of `{}` was terminated as its execution exceeded the timeout of {} seconds. Please refactor your code!" .format(fn, component, self._execution_timeout)) except Exception as e: # pylint: disable=broad-except if self._skills_exception_policy == ExceptionPolicyEnum.propagate: raise elif self._skills_exception_policy == ExceptionPolicyEnum.just_log: log_exception(e, fn, component) elif self._skills_exception_policy == ExceptionPolicyEnum.stop_and_exit: log_exception(e, fn, component) self.stop() raise AEAException( f"AEA was terminated cause exception `{e}` in skills {component} {fn}! Please check logs." ) else: raise AEAException( f"Unsupported exception policy: {self._skills_exception_policy}" )