How to retrieve contextvars from an async task in asyncio loop on exception_handler when unhandled occurred

Cannot retrieve contextvars from a Task(Future) in asyncio loop in exception_handler when an unhandled occurred.

I use contextvars to keep track of the application context and use the information to debug but when an unhandled error occurred, I could not retrieve the information stored in the contextvars. How can I retrieve the async task contextvars?

Example code:

import asyncio
import contextvars

status_var = contextvars.ContextVar('status', default='zzzz')


def loop_error_handler(loop, context) -> None:
    print(status_var.get())  # 'zzzz' but it should be 'BOOM!'
    # Try to get 'BOOM!' from context['future']
    task = context['future']
    print(task._context)  # Not found _context


async def work():
    status_var.set('BOOM!')  # Set status_var to 'BOOM!'
    num = 1 / 0  # Unhandled error
    print(num)


async def main():
    loop = asyncio.get_event_loop()
    loop.set_exception_handler(loop_error_handler)
    loop.create_task(work())


if __name__ == '__main__':
    asyncio.run(main())

Environment

  • Python versions tested on: Python 3.10
  • Operating system and architecture: MacOS, macos_arm64