chore(lint): interdire d avaler une exception sans laisser de trace
Regle BLE de ruff activee. Ce qu'elle enforce n'est pas "ne jamais attraper large" : elle se satisfait d'un logger.exception. C'est exactement la discipline visee — une frontiere peut tout avaler, a condition de laisser de quoi distinguer un defaut d'une panne. Les cinq noqa que j'avais prepares d'avance etaient donc inertes ; la raison reste en commentaire simple. Ce que la regle a trouve, une fois activee : app.py, demarrage du bot — les deux facons d'echouer, jeton invalide et import casse, se lisaient a l'identique sur une seule ligne et aucune n'etait diagnosticable. Passe en error avec exc_info : un club qui ne recoit plus aucun rappel a perdu une fonctionnalite, et warning mettait ca a cote des avis de depreciation. services/notifications.py — le bloc webhook attrapait large autour d'un requests.post. RequestException couvre toutes les facons dont un appel HTTP echoue ; le reste est un defaut. La branche DM et la branche webhook etaient en plus imbriquees dans un seul try alors qu'elles s'excluent. logging_config.py et les deux scripts CLI gardent leur largeur, avec la raison sur la ligne. Le filtre de journalisation est le cas ou la trace que BLE001 reclame est precisement ce qu'il ne faut pas produire : journaliser depuis un filtre rentre dans le meme filtre. RUF100 (noqa inutile) n'est volontairement pas active : il ferait remonter des directives preexistantes sans rapport avec ce chantier. Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
@@ -4,10 +4,15 @@ Extracted from app/routes/users.py, where it sat between two route
|
||||
definitions and pulled `requests`, `logging` and the Discord bot into a
|
||||
module whose subject is HTTP handlers (ARCH-003).
|
||||
|
||||
Every failure here is swallowed and logged on purpose: a notification that
|
||||
does not reach Discord must not roll back the session it was announcing.
|
||||
That is the one place in this codebase where `except Exception` is the
|
||||
right answer rather than an oversight.
|
||||
Failures here are swallowed and logged on purpose: a notification that does
|
||||
not reach Discord must not roll back the session it was announcing. That is
|
||||
a property of the caller — a Flask request whose work is already committed —
|
||||
not of the failure, which is why the breadth is argued for at each of the
|
||||
two boundaries below rather than assumed (ARCH-008 / QUA-004).
|
||||
|
||||
The webhook branch is narrower than it was: `requests.RequestException`
|
||||
covers every way an HTTP call can fail, and anything else coming out of it
|
||||
is a defect worth seeing.
|
||||
"""
|
||||
|
||||
import logging
|
||||
@@ -61,56 +66,62 @@ def send_discord_notification(
|
||||
points=points,
|
||||
request_id=request_id,
|
||||
)
|
||||
except Exception as e:
|
||||
logger.warning(f"Failed to send Discord DM: {e}")
|
||||
except Exception: # noqa: BLE001 — the request that booked the meeting is already committed
|
||||
logger.warning('Failed to hand the One on One DM to the bot', exc_info=True)
|
||||
|
||||
if DISCORD_WEBHOOK_URL:
|
||||
try:
|
||||
if not DISCORD_WEBHOOK_URL:
|
||||
return
|
||||
|
||||
# A bare snowflake here means "DM this person instead", and only when the
|
||||
# coach has no id of their own. Queueing it cannot raise (see _enqueue).
|
||||
if DISCORD_WEBHOOK_URL.isdigit():
|
||||
if not coach_discord_id:
|
||||
from app.discord_bot import send_one_on_one_dm
|
||||
|
||||
if DISCORD_WEBHOOK_URL.isdigit() and not coach_discord_id:
|
||||
send_one_on_one_dm(
|
||||
coach_name=coach_name,
|
||||
coach_discord_id=DISCORD_WEBHOOK_URL,
|
||||
player_name=player_name,
|
||||
team_name=team_name,
|
||||
date_str=date_str,
|
||||
start_time=start_time_str,
|
||||
end_time=end_time_str,
|
||||
points=points,
|
||||
)
|
||||
elif not DISCORD_WEBHOOK_URL.isdigit():
|
||||
embed = {
|
||||
"embeds": [
|
||||
{
|
||||
"title": "One on One Request",
|
||||
"color": 3447003,
|
||||
"fields": [
|
||||
{"name": "Player", "value": player_name, "inline": True},
|
||||
{
|
||||
"name": "Team",
|
||||
"value": team_name or "Unknown Team",
|
||||
"inline": True,
|
||||
},
|
||||
{"name": "Date", "value": date_str, "inline": True},
|
||||
{
|
||||
"name": "Time",
|
||||
"value": f"{start_time_str} - {end_time_str}",
|
||||
"inline": True,
|
||||
},
|
||||
{
|
||||
"name": "Discussion Points",
|
||||
"value": points or "No specific points provided",
|
||||
"inline": False,
|
||||
},
|
||||
],
|
||||
"footer": {
|
||||
"text": f"Coach: {coach_name}"
|
||||
+ (f" (Discord: {coach_discord})" if coach_discord else ""),
|
||||
},
|
||||
}
|
||||
],
|
||||
}
|
||||
requests.post(DISCORD_WEBHOOK_URL, json=embed, timeout=5)
|
||||
except Exception as e:
|
||||
logger.warning(f"Failed to send Discord notification: {e}")
|
||||
send_one_on_one_dm(
|
||||
coach_name=coach_name,
|
||||
coach_discord_id=DISCORD_WEBHOOK_URL,
|
||||
player_name=player_name,
|
||||
team_name=team_name,
|
||||
date_str=date_str,
|
||||
start_time=start_time_str,
|
||||
end_time=end_time_str,
|
||||
points=points,
|
||||
)
|
||||
return
|
||||
|
||||
embed = {
|
||||
"embeds": [
|
||||
{
|
||||
"title": "One on One Request",
|
||||
"color": 3447003,
|
||||
"fields": [
|
||||
{"name": "Player", "value": player_name, "inline": True},
|
||||
{
|
||||
"name": "Team",
|
||||
"value": team_name or "Unknown Team",
|
||||
"inline": True,
|
||||
},
|
||||
{"name": "Date", "value": date_str, "inline": True},
|
||||
{
|
||||
"name": "Time",
|
||||
"value": f"{start_time_str} - {end_time_str}",
|
||||
"inline": True,
|
||||
},
|
||||
{
|
||||
"name": "Discussion Points",
|
||||
"value": points or "No specific points provided",
|
||||
"inline": False,
|
||||
},
|
||||
],
|
||||
"footer": {
|
||||
"text": f"Coach: {coach_name}"
|
||||
+ (f" (Discord: {coach_discord})" if coach_discord else ""),
|
||||
},
|
||||
}
|
||||
],
|
||||
}
|
||||
try:
|
||||
requests.post(DISCORD_WEBHOOK_URL, json=embed, timeout=5)
|
||||
except requests.RequestException as exc:
|
||||
logger.warning('Failed to post the One on One webhook: %s', exc)
|
||||
|
||||
Reference in New Issue
Block a user