10

I have this code:

try:
    asyncio.ensure_future(data_streamer.sendByLatest())
except ValueError as e:
    logging.debug(repr(e))

data_streamer.sendByLatest() can raise a ValueError, but it is not caught.

Marco Sulla
  • 15,299
  • 14
  • 65
  • 100

1 Answers1

13

ensure_future - just creates Task and return immediately. You should await for created task to get it's result (including case when it raises exception):

import asyncio


async def test():
    await asyncio.sleep(0)
    raise ValueError('123')


async def main():    
    try:
        task = asyncio.ensure_future(test())  # Task aren't finished here yet 
        await task  # Here we await for task finished and here exception would be raised 
    except ValueError as e:
        print(repr(e))


if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())

Output:

ValueError('123',)

In case you aren't planning to await task immediately after you created it, you can await it later (to know how it has finished):

async def main():    
    task = asyncio.ensure_future(test())
    await asyncio.sleep(1)
    # At this moment task finished with exception,
    # but we didn't retrieved it's exception.
    # We can do it just awaiting task:
    try:
        await task  
    except ValueError as e:
        print(repr(e)) 

Output is same:

ValueError('123',)
Mikhail Gerasimov
  • 36,989
  • 16
  • 116
  • 159
  • Thank you. Do you know also how to catch exceptions with `call_soon_threadsafe()`? – Marco Sulla May 03 '16 at 13:16
  • @MarcoSulla sorry, I don't know. One way I see is to use wrapper to handle exception in callback: http://pastebin.com/rNyTWMBk but I don't know if it's common way to do it. – Mikhail Gerasimov May 03 '16 at 14:29