fix: tolerate season-reset payloads in /sq-info and stop duplicate error embeds
obtain_clan_new_points treated a missing `astat` or `member_ratings` block as "squadron unavailable or deleted". After a season reset the game API omits those blocks for inactive/unranked squadrons even though the clan and its roster still exist, so /sq-info wrongly reported real squadrons (e.g. DSPL, 513th) as nonexistent. Require a `members` roster to consider the payload valid (genuinely deleted clans return CLAN_IS_NOT_EXISTS JSON handled upstream) and default both stat blocks to zero, so the squadron renders at 0 points instead of erroring. permission_fail was invoked twice per error because discord.py dispatches to both the command-local `@cmd.error` handler and the global `@tree.error` handler. Combined with a public defer, this produced a duplicated error message (one public, one ephemeral). Guard on interaction.extras so the embed is sent at most once per interaction. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -598,6 +598,15 @@ def gate_entitle(required_tier: str):
|
||||
|
||||
async def permission_fail(interaction: discord.Interaction, error):
|
||||
"""Handle permission-related errors with appropriate embeds."""
|
||||
# discord.py dispatches a command error to BOTH the command's local
|
||||
# `@cmd.error` handler and the global `@tree.error` handler (see
|
||||
# app_commands/tree.py). Since both route here, guard against sending the
|
||||
# error embed twice for the same interaction — the second send would land
|
||||
# as a separate (and, after a public defer, differently-scoped) message.
|
||||
if interaction.extras.get("_permission_fail_handled"):
|
||||
return
|
||||
interaction.extras["_permission_fail_handled"] = True
|
||||
|
||||
lang = await guild_lang(interaction.guild_id) if interaction.guild_id else "en"
|
||||
if isinstance(error, BlacklistCheckFailure):
|
||||
reason = getattr(error, "reason", None)
|
||||
|
||||
Reference in New Issue
Block a user