0

I am specifically using python version 3.10 to run a websocket (or any long asyncio process) for a specified period of time which is covered in the python docs. The .wait_for() method looks like the correct solution.

I run this code (from the docs):

import asyncio

async def eternity():
    # Sleep for one hour
    await asyncio.sleep(3600)
    print('yay!')

async def main():
    # Wait for at most 1 second
    print('wait for at most 1 second...')
    try:
        await asyncio.wait_for(eternity(), timeout=1.0)
    except TimeoutError: 
        print('timeout!')


asyncio.run(main())

The docs are here: https://docs.python.org/3/library/asyncio-task.html?highlight=wait_for#asyncio.wait_for

However, I get the following error:

Exception has occurred: TimeoutError
exception: no description

...basically, the TimeoutError exception is not handled as expected.

My research shows that others have struggled with errors, for example here: Handling a timeout error in Python sockets

but the fixes are either aged (not relevant for 3.10) or do not work. I also notice that the docs specify this "Changed in version 3.10: Removed the loop parameter". So i am only interested in version 3.10 and above.

So I am wondering how to get the min reproducible example working or what i have done wrong please ?

D.L
  • 4,339
  • 5
  • 22
  • 45

2 Answers2

1

You can remove the TimeoutError so it can jump down to the print('timeout') or can use this example to output the error

except Exception as exc:
    print(f'The exception: {exc!r}')
  • I was going to post similar as a solution, but this catches other errors, whereas ideally like to catch the `TimeoutError`.... what did the `!r` do ? i have not seen this before ?!? – D.L Nov 20 '22 at 17:59
  • I have upvoted this because it works. although i have used this `print('some exception...', type(e))`... – D.L Nov 20 '22 at 18:09
  • I don't know what "!r" is for, but it seems to be forcing the string, I also found it in the website you sent me. – Zz_GhostM4n_zZ Nov 20 '22 at 18:17
  • 1
    In an f-string, `{exc!r}` is replaced by `repr(exc)`. `{exc}` is replaced by `str(exc)`. See https://docs.python.org/3/tutorial/inputoutput.html – Paul Cornelius Nov 22 '22 at 03:34
  • @Paul Cornelius this knowledge is new to me, thank you for answering the question – Zz_GhostM4n_zZ Nov 22 '22 at 10:36
  • @PaulCornelius. was unaware of this. So basically, `Exception as e: ... print(str(e))` would have been sufficient. – D.L Nov 23 '22 at 08:48
  • print(repr(exc)) is the equivalent of print(f"{exc!r}"). print(exc), print(str(exc)), print(f"{exc}") and print(f"{exc!s}") are essentially the same thing. I'm not sure what's the difference in actual output between repr(exc) and str(exc) when exc is an Exception. With exceptions I almost always print the full traceback (traceback.print_exc()) or use Python's logging features. – Paul Cornelius Nov 23 '22 at 11:30
0

There are a number of TimeoutErrors in Python.

Replace except TimeoutError with except asyncio.TimeoutError and you’ll be good.

UPDATE with full example:

import asyncio

async def eternity():
    # Sleep for one hour
    await asyncio.sleep(3600)
    print('yay!')

async def main():
    # Wait for at most 1 second
    print('wait for at most 1 second...')
    try:
        await asyncio.wait_for(eternity(), timeout=1.0)
    except asyncio.TimeoutError: 
        print('timeout!')

asyncio.run(main())

Apparently the example in asyncio’s docs is wrong (or at least misleading). If you look at CPython’s source code, asyncio.TimeoutError is a different exception from TimeoutError up to Python 3.10, and was changed to an alias to TimeoutError in 3.11.

fancidev
  • 144
  • 1
  • 4
  • noted and appreciated. I actually went for this `except Exception as e: ... if str(type(e)) == "":` as it catches all errors and filters for the `asyncio.exceptions.TimeoutError` error. If you have a code example that would be most helpful. – D.L Nov 23 '22 at 08:38