def background_task_callback(task: asyncio.Task) -> None: """Check if the finished background task failed to make sure we log errors.""" if task.cancelled(): log.info(f"Background task `{task.get_name()}` was cancelled.") elif exception := task.exception(): log.error(f"Background task `{task.get_name()}` failed:", exc_info=exception)
def task_callback(task: asyncio.Task) -> None: with contextlib.suppress(asyncio.CancelledError, asyncio.InvalidStateError): if exc := task.exception(): log.exception("%s raised an Exception", task.get_name(), exc_info=exc)
def callback(task: Task): if task.exception(): _LOG.warning( "Unable to connect to newly discovered controller", exc_info=task.exception()) return self._controllers[device_uid] = controller self.controller_discovered(controller)
def ui_closed(self, task: asyncio.Task) -> None: if task.exception(): self.logger.error("UI failed with an exception: %s", task.exception()) self.returncode = 1 else: self.returncode = task.result() self.stop_event.set()
def task_result_callback(task: asyncio.Task) -> None: """Check if our sleep task ended in an expected way.""" name = task.get_name() if task.cancelled(): log.debug(f"{name} task callback: the task was cancelled") return if exc := task.exception(): log.exception(f"{name} task callback: the task failed!", exc_info=exc)
def _task_done_callback(self, task: asyncio.Task) -> None: """Remove task on done, log error if happened.""" self._tasks.remove(task) if task.exception(): # cause task.get_name for python3.8+ task_name = getattr(task, "task_name", "TASK NAME NOT SET") self.logger.exception( f"in task `{task_name}`, exception occured", exc_info=task.exception(), )
def _recv_task_finalizer(self, task: Task): self._logger.debug("%s Recv task closed" % repr(self)) self._recv_task = None # noinspection PyUnresolvedReferences self._recv_queue._queue.clear( ) # By some reason this method isn't exposed. Not sure if it is a good idea. if not task.cancelled() and task.exception(): self._logger.error("%s: RECV err %s" % (repr(self), task.exception()))
def update_view(future: asyncio.Task): try: future.exception() except asyncio.CancelledError: pass except Exception as E: raise E layout = self.pipe.outlet.value self.view.source.value = layout self.pipe.inlet.value = layout self.pipe.inlet.flow = tuple()
async def get_response_item_count(task: Task, done: Set[Awaitable], pending: Set[Awaitable], error_msg: str) -> Optional[int]: if task in done and task.exception() is None: return len(await task.result().json()) elif task in pending: task.cancel() else: logging.exception(error_msg, exc_info=task.exception()) return None
def __call_async_cb(self, task: asyncio.Task, callback: Optional[Callable[[Any], None]]) -> None: if task.exception() is not None: buf = io.StringIO() task.print_stack(file=buf) self.__app.crashWithMessage("Exception in callback", buf.getvalue()) raise task.exception() if callback is not None: callback(task.result())
def post_run(future: asyncio.Task): with self.log_out: failed = False try: future.exception() except asyncio.CancelledError: print("Diagram update was cancelled!") except Exception as exc: failed = True raise exc finally: button.disabled = failed
def _on_reader_done(self, task: asyncio.Task) -> None: log.debug("Reader exited for %r", self) if not self._writer_task.done(): self._writer_task.cancel() if not task.cancelled() and task.exception() is not None: log.debug("Cancelling cause reader exited abnormally") self.set_close_reason( reply_code=500, reply_text="reader unexpected closed", ) self.create_task(self.close(task.exception()))
def add_to_map(self, url: str, action: Method, fut: asyncio.Task, **kwargs) -> None: if fut.exception(): _logger.warning(f"Can't {action.value} on {url}: {fut.exception()}") self.hook_add_to_map_error(url=url, action=action, fut=fut, **kwargs) return sub_name = kwargs.pop("sub_name") if action == Method.ADD_SUB: vs = VirtualSubscription(**kwargs) self.real_map[url][sub_name] = vs self.name_to_subscription[url][sub_name] = fut.result() if action == Method.ADD_MI: nodes = kwargs["nodes"] vs = self.real_map[url][sub_name] vs.subscribe_data_change(nodes, *astuple(kwargs["node_attr"])) for node, handle in zip(nodes, fut.result()): if isinstance(handle, ua.StatusCode): # a StatusCode is returned, the request has failed. vs.unsubscribe([node]) _logger.info(f"Node {node} subscription failed: {handle}") # The node is invalid, remove it from both maps if handle.name == "BadNodeIdUnknown": _logger.warning( f"WARNING: Abandoning {node} because it returned {handle} from {url}" ) real_vs = self.ha_client.ideal_map[url][sub_name] real_vs.unsubscribe([node]) continue self.node_to_handle[url][node] = handle self.hook_add_to_map(fut=fut, url=url, action=action, **kwargs)
def handle_task_error(self, task: asyncio.Task, request: Request) -> None: """ Handle the non-successful execution of a handler task, effectively this writes and closes the transport. :param task: Completed task, task.exception() is not None :param request: Original request :return: None """ # TODO: Log the exception, map to a different statuses exc = task.exception() print('exception:', exc) if isinstance(exc, HTTPException): status = exc.status message = str(exc) else: status = HTTPStatus.INTERNAL_SERVER_ERROR message = '' self.transport.write( (b'HTTP/%b %d %b\r\n' b'Content-Type: text/plain\r\n' b'Content-Length: %d\r\n' b'\r\n' b'%b') % (request.version.encode(), status.value, status.phrase.encode(), len(message), message.encode()))
def task_complete(self, task: asyncio.Task): if task.cancelled(): return if task.exception(): task.print_stack() self.keep_alive = self.loop.create_task(self.rebooter()) self.keep_alive.add_done_callback(self.task_complete)
def _task_done_callback(self, task_id: t.Hashable, done_task: asyncio.Task) -> None: """ Delete the task and raise its exception if one exists. If `done_task` and the task associated with `task_id` are different, then the latter will not be deleted. In this case, a new task was likely rescheduled with the same ID. """ self._log.info( f"Performing done callback for task #{task_id} {id(done_task)}.") scheduled_task = self._scheduled_tasks.get(task_id) if scheduled_task and done_task is scheduled_task: # A task for the ID exists and is the same as the done task. # Since this is the done callback, the task is already done so no need to cancel it. self._log.info(f"Deleting task #{task_id} {id(done_task)}.") del self._scheduled_tasks[task_id] elif scheduled_task: # A new task was likely rescheduled with the same ID. self._log.debug( f"The scheduled task #{task_id} {id(scheduled_task)} " f"and the done task {id(done_task)} differ.") elif not done_task.cancelled(): self._log.warning( f"Task #{task_id} not found while handling task {id(done_task)}! " f"A task somehow got unscheduled improperly (i.e. deleted but not cancelled)." ) with contextlib.suppress(asyncio.CancelledError): exception = done_task.exception() # Log the exception if one exists. if exception: self._log.error(f"Error in task #{task_id} {id(done_task)}!", exc_info=exception)
def _task_done(self, task: asyncio.Task) -> None: self._tasks.remove(task) if task.cancelled(): return exc = task.exception() if exc is not None: raise exc
def _worker_done(self, task: asyncio.Task) -> None: assert task is self._worker_task if task.cancelled(): self._connection_task.cancel() elif task.exception(): f = io.StringIO() task.print_stack(file=f) self.logger.error(f.getvalue()) now = time.time() self._worker_task_failure_timestamps.append(time.time()) if len(self._worker_task_failure_timestamps) == 5: if self._worker_task_failure_timestamps.pop(0) >= now - 10: self.logger.error( "Worker task exceeded exception threshold; terminating" ) self._close("Exception threshold exceeded") return self.logger.warning("Restarting worker task") self._worker_task = self.loop.create_task(self._worker()) self._worker_task.add_done_callback(self._worker_done) else: self.logger.debug("Worker task exited gracefully") return
def _task_done(self, task: Task) -> None: with self._lock: coroutine = self._task_map.pop(task) try: if task.exception() and self.stack_limit: task.print_stack(limit=None if self.stack_limit is True else self.stack_limit, file=self.stack_file) except CancelledError: coroutine.close()
def check_task_exception(self, fut: asyncio.Task): if fut.done(): try: exc = fut.exception() except asyncio.CancelledError as e: exc = e if exc: self.log(f"Task raised exception: {str(exc)}")
def _log_task_exception(task: asyncio.Task) -> None: """Retrieve and log the exception raised in `task` if one exists.""" with contextlib.suppress(asyncio.CancelledError): exception = task.exception() # Log the exception if one exists. if exception: log = logging.getLogger(__name__) log.error(f"Error in task {task.get_name()} {id(task)}!", exc_info=exception)
def handle_error(self, task: asyncio.Task): try: exception = task.exception() except (asyncio.CancelledError, RecursionError): return if exception is not None: self.create_task(self.on_error("task", exception))
def cancel_trio(task: asyncio.Task) -> None: ''' Cancel the calling ``trio`` task on error. ''' nonlocal chan aio_err = chan._aio_err task_err: Optional[BaseException] = None # only to avoid ``asyncio`` complaining about uncaptured # task exceptions try: task.exception() except BaseException as terr: task_err = terr log.exception(f'`asyncio` task: {task.get_name()} errored') assert type(terr) is type(aio_err), 'Asyncio task error mismatch?' if aio_err is not None: # XXX: uhh is this true? # assert task_err, f'Asyncio task {task.get_name()} discrepancy!?' # NOTE: currently mem chan closure may act as a form # of error relay (at least in the ``asyncio.CancelledError`` # case) since we have no way to directly trigger a ``trio`` # task error without creating a nursery to throw one. # We might want to change this in the future though. from_aio.close() if type(aio_err) is CancelledError: log.cancel("infected task was cancelled") # TODO: show that the cancellation originated # from the ``trio`` side? right? # if cancel_scope.cancelled: # raise aio_err from err elif task_err is None: assert aio_err aio_err.with_traceback(aio_err.__traceback__) msg = ''.join(traceback.format_exception(type(aio_err))) log.error(f'infected task errorred:\n{msg}') # raise any ``asyncio`` side error. raise aio_err
def track_done(fut: asyncio.Task): if fut.cancelled(): return # todo sth to do in this case? trackExc = fut.exception() if trackExc is not None: logger.error( f"Failed tracking job for ips={ips!r} - {trackExc!s}\n{track_task.get_stack()!s}" ) worker.peer.stop()
def _task_done(self, actx: ActivityContext, task: asyncio.Task) -> None: actx.tasks.remove(task) if task.cancelled(): return exc = task.exception() if exc is not None: msg = f"Task failed. {exc.__class__.__name__}: {exc}" self.set_status(("error message", msg)) return
def _on_read_loop_task_done(self, t: asyncio.Task): try: e = t.exception() if e is not None: raise e except asyncio.CancelledError: pass except Exception: logger.exception('read_loop() exited with error', exc_info=True)
def _default_cb(self, t: asyncio.Task) -> None: """A simple callback for tasks to log & call exc handler.""" if not t.cancelled(): exc = t.exception() if exc and not isinstance(exc, (SystemExit, KeyboardInterrupt)): self.exceptions += 1 loop = asyncio.get_running_loop() loop.default_exception_handler({'exception': exc})
def task_exc_info(task: asyncio.Task): """Extract exception info from an asyncio task.""" if not task or not task.done(): return try: exc_val = task.exception() except asyncio.CancelledError: exc_val = asyncio.CancelledError("Task was cancelled") if exc_val: return type(exc_val), exc_val, exc_val.__traceback__
def maybe_cancel_clbk(t: asyncio.Task): exception = t.exception() if exception is None: return for task in asyncio.all_tasks(): coro = task.get_coro() if coro.__qualname__ == request.function.__qualname__: task.cancel() return
def callback(done_task: asyncio.Task): e = done_task.exception() if e: logger.debug("Error occurred in process_offer") logger.debug(e) self._answer_queue.put(e) return localDescription = done_task.result() self._answer_queue.put(localDescription)