Source code for nanome.util.asyncio

import asyncio
import inspect
import logging
import sys
from concurrent.futures._base import CancelledError
from . import Logs


[docs]async def handle_exception(exc_type, exc_value, exc_traceback): """Make sure uncaught exceptions are logged.""" if issubclass(exc_type, KeyboardInterrupt): sys.__excepthook__(exc_type, exc_value, exc_traceback) return # Get the module where error originated from the traceback frm = inspect.trace()[-1] mod = inspect.getmodule(frm[0]) mod_name = mod.__name__ if mod else frm[1] if mod_name: logger = logging.getLogger(mod_name) else: logger = logging.getLogger() logger.error("Uncaught {}: {}".format(exc_type.__name__, exc_value), exc_info=1) await asyncio.sleep(0.1) # Give log a split second to process
[docs]async def exception_wrapper(fn, args, kwargs): """Wrap all callbacks to catch exceptions. Based on this documentation https://docs.python.org/3.6/library/asyncio-dev.html?highlight=exception#detect-exceptions-never-consumed """ try: return await fn(*args, **kwargs) except CancelledError: # A user exiting and cancelling the request should not be logged as an error. Logs.message("Request was cancelled by the user.") except Exception: exc_type, exc_value, exc_traceback = sys.exc_info() await handle_exception(exc_type, exc_value, exc_traceback)
[docs]def async_callback(fn): def task(*args, **kwargs): fut = asyncio.create_task(exception_wrapper(fn, args, kwargs)) return fut return task