I run a small script before client check-ins that scores each client's site from three metrics, with per-client weights fetched from their analytics endpoint. The fetches go through asyncio.gather with return_exceptions=True, so one broken client doesn't cancel the rest, right? fetch_weights raises ValueError when the response is empty, and I wrapped the gather in try/except ValueError to log a warning and fall back to the default weights.
The first client prints a score, then the script dies on eastside-cycles, which has an empty response. There's no "falling back to defaults" warning at all. I changed it to except Exception, and I ran it with python3 -X dev main.py, and neither changed anything.
The part I don't get is that the TypeError mentions a ValueError object, even though the ValueError is clearly raised in fetch_weights.
juniper-florals: 83.0
Traceback (most recent call last):
File "main.py", line 59, in <module>
main()
File "main.py", line 55, in main
asyncio.run(score_all(clients))
...
File "main.py", line 40, in score_all
value = score(client["metrics"], weights)
File "main.py", line 26, in score
return round(sum(metrics[k] * weights[k] for k in weights), 1)
TypeError: 'ValueError' object is not iterable
The relevant part of main.py:
async def score_all(clients):
try:
all_weights = await asyncio.gather(
*(fetch_weights(c) for c in clients),
return_exceptions=True,
)
except ValueError:
log.warning("weights fetch failed, falling back to defaults")
all_weights = [DEFAULT_WEIGHTS for _ in clients]
for client, weights in zip(clients, all_weights):
value = score(client["metrics"], weights)
print(client["slug"] + ": " + str(value))
Why is the handler skipped?