diff options
| author | 2020-09-30 00:19:39 +0200 | |
|---|---|---|
| committer | 2020-10-10 15:03:38 +0200 | |
| commit | d8c36ac9f189ba9638ef91df7628f95845161f8e (patch) | |
| tree | e3fadeb7e91eeced7fce0c90273cdbef2e5f667a | |
| parent | Add async implementation of sphinx fetch_inventory (diff) | |
Handle errors on inventory fetching
Diffstat (limited to '')
| -rw-r--r-- | bot/cogs/doc/inventory_parser.py | 37 | 
1 files changed, 35 insertions, 2 deletions
| diff --git a/bot/cogs/doc/inventory_parser.py b/bot/cogs/doc/inventory_parser.py index 6c2b63d5e..23931869b 100644 --- a/bot/cogs/doc/inventory_parser.py +++ b/bot/cogs/doc/inventory_parser.py @@ -1,10 +1,14 @@ +import logging  import re  import zlib  from collections import defaultdict -from typing import AsyncIterator, DefaultDict, List, Tuple +from typing import AsyncIterator, DefaultDict, List, Optional, Tuple  import aiohttp +log = logging.getLogger(__name__) + +FAILED_REQUEST_ATTEMPTS = 3  _V2_LINE_RE = re.compile(r'(?x)(.+?)\s+(\S*:\S*)\s+(-?\d+)\s+?(\S*)\s+(.*)') @@ -65,7 +69,7 @@ async def _load_v2(stream: aiohttp.StreamReader) -> DefaultDict[str, List[Tuple[      return invdata -async def fetch_inventory(client_session: aiohttp.ClientSession, url: str) -> DefaultDict[str, List[Tuple[str, str]]]: +async def _fetch_inventory(client_session: aiohttp.ClientSession, url: str) -> DefaultDict[str, List[Tuple[str, str]]]:      """Fetch, parse and return an intersphinx inventory file from an url."""      timeout = aiohttp.ClientTimeout(sock_connect=5, sock_read=5)      async with client_session.get(url, timeout=timeout, raise_for_status=True) as response: @@ -85,3 +89,32 @@ async def fetch_inventory(client_session: aiohttp.ClientSession, url: str) -> De              return await _load_v2(stream)          raise ValueError(f"Invalid inventory file at url {url}.") + + +async def fetch_inventory( +        client_session: aiohttp.ClientSession, +        url: str +) -> Optional[DefaultDict[str, List[Tuple[str, str]]]]: +    """Get inventory from `url`, retrying `FAILED_REQUEST_ATTEMPTS` times on errors.""" +    for attempt in range(1, FAILED_REQUEST_ATTEMPTS+1): +        try: +            inventory = await _fetch_inventory(client_session, url) +        except aiohttp.ClientConnectorError: +            log.warning( +                f"Failed to connect to inventory url at {url}, " +                f"trying again ({attempt}/{FAILED_REQUEST_ATTEMPTS})." +            ) +        except aiohttp.ClientError: +            log.error( +                f"Failed to get inventory from {url}, " +                f"trying again ({attempt}/{FAILED_REQUEST_ATTEMPTS})." +            ) +        except Exception: +            log.exception( +                f"An unexpected error has occurred during fetching of {url}, " +                f"trying again ({attempt}/{FAILED_REQUEST_ATTEMPTS})." +            ) +        else: +            return inventory + +    return None | 
