r/protonvpn: watchdog: Improve error handling

This resolves two issues with fetching the Proton VPNserver list:

1. If a connection error occurs when fetching the list, it will be
   ignored, just as with HTTP errors
2. If any errors are encountered when fetching the list, and a valid
   cache was loaded, its contents are returned, regardless of the
   timestamp of the cache file.
collectd-buildroot
Dustin 2022-03-01 21:28:21 -06:00
parent 5485fc6f93
commit 5e2cfee8a1
1 changed files with 14 additions and 12 deletions

View File

@ -111,34 +111,36 @@ class AsyncDaemon(BaseAsyncDaemon):
self.bad_servers: Set[str] = set()
async def get_serverlist(self) -> Optional[Json]:
data: Optional[Json] = None
try:
f = open(self.SERVER_LIST, encoding='utf-8')
except FileNotFoundError:
pass
else:
with f:
try:
data = json.load(f)
except ValueError as e:
log.warning('Failed to parse server list: %s', e)
st = os.fstat(f.fileno())
now = time.time()
if st.st_mtime > now - 3600:
log.info('Using cached server list from %s', f.name)
try:
return json.load(f)
except ValueError as e:
log.warning('Failed to parse server list: %s', e)
return data
async with httpx.AsyncClient() as client:
log.info('Fetching server list from %s', self.SERVER_LIST_URL)
r: httpx.Response = await client.get(self.SERVER_LIST_URL)
if r.status_code != HTTPStatus.OK:
log.error(
'Failed to fetch server list: HTTP status %s',
r.status_code,
)
return None
r: httpx.Response
try:
r = await client.get(self.SERVER_LIST_URL)
r.raise_for_status()
except httpx.HTTPError as e:
log.error('Failed to fetch server list: %s', e)
return data
try:
data = r.json()
except ValueError as e:
log.error('Failed to parse server list: %s', e)
return None
return data
path = Path(self.SERVER_LIST)
path.parent.mkdir(parents=True, exist_ok=True)
with path.open('w', encoding='utf-8') as f: