Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

impossible to catch asyncio.TimeoutError?

I'm using asyncio to fetch url's and sometimes they timeout, try as I might, I cannot catch the asyncio.TimeoutError with the following code!

async def fetch(url, session):
    """Fetch a url, using specified ClientSession."""
    async with session.get(url) as response:
        # print(f"fetching {url}")
        try:
            resp = await response.read()
        except asyncio.TimeoutError:
            return {"results": f"timeout error on {url}"}

        if response.status != 200:
            return {"error": f"server returned {response.status}"}

        return str(resp, 'utf-8').rstrip()

Here's the stack trace. What can I do to catch this exception and log it rather than exiting my program?

 resource: {…}  
 severity:  "ERROR"  
 textPayload:  "Traceback (most recent call last):
  File "/env/local/lib/python3.7/site-packages/google/cloud/functions/worker.py", line 346, in run_http_function
    result = _function_handler.invoke_user_function(flask.request)
  File "/env/local/lib/python3.7/site-packages/google/cloud/functions/worker.py", line 217, in invoke_user_function
    return call_user_function(request_or_event)
  File "/env/local/lib/python3.7/site-packages/google/cloud/functions/worker.py", line 210, in call_user_function
    return self._user_function(request_or_event)
  File "/user_code/main.py", line 230, in gcf_update_all_featured_podcasts
    loop.run_until_complete(future)  # loop until done
  File "/opt/python3.7/lib/python3.7/asyncio/base_events.py", line 573, in run_until_complete
    return future.result()
  File "/user_code/main.py", line 201, in fetch_all
    _ = await asyncio.gather(*tasks)  # gather task responses
  File "/user_code/main.py", line 181, in fetch
    async with session.get(url) as response:
  File "/env/local/lib/python3.7/site-packages/aiohttp/client.py", line 1005, in __aenter__
    self._resp = await self._coro
  File "/env/local/lib/python3.7/site-packages/aiohttp/client.py", line 497, in _request
    await resp.start(conn)
  File "/env/local/lib/python3.7/site-packages/aiohttp/client_reqrep.py", line 857, in start
    self._continue = None
  File "/env/local/lib/python3.7/site-packages/aiohttp/helpers.py", line 585, in __exit__
    raise asyncio.TimeoutError from None
concurrent.futures._base.TimeoutError
like image 433
Jason Avatar asked Aug 04 '19 20:08

Jason


1 Answers

In your traceback you can see that exception is raised from line where you are trying to make request to url, but your try block is on one level below.

Try like this:

async def fetch(url, session):
"""Fetch a url, using specified ClientSession."""
    try:
         async with session.get(url) as response:
         # print(f"fetching {url}")
            resp = await response.read()
            if response.status != 200:
                return {"error": f"server returned {response.status}"}

            return str(resp, 'utf-8').rstrip()

    except asyncio.TimeoutError:
        return {"results": f"timeout error on {url}"}
like image 50
4xel Avatar answered Oct 18 '22 21:10

4xel