add error handling to render pipeline, graceful portrait fallback
This commit is contained in:
1 parent
6dbd8f09ca
commit
9faacbc519
2 files changed
+22
-3
No files matched your search
+14
-1
@@ -267,16 +267,29 @@ class BlueArchiveGacha(commands.Cog):
|
|||||||
|
|
||||||
# Render result image
|
# Render result image
|
||||||
spark = user_state["spark"]
|
spark = user_state["spark"]
|
||||||
|
try:
|
||||||
async with ctx.typing():
|
async with ctx.typing():
|
||||||
img_bytes = await render_pull(pulls, banner_name, spark)
|
img_bytes = await render_pull(pulls, banner_name, spark)
|
||||||
|
except Exception as e:
|
||||||
|
log.exception("Render failed")
|
||||||
|
try:
|
||||||
|
await teaser.delete()
|
||||||
|
except (discord.NotFound, discord.Forbidden):
|
||||||
|
pass
|
||||||
|
await ctx.reply(f"Render failed: {e}")
|
||||||
|
return
|
||||||
|
|
||||||
# Send image only — the picture says it all
|
# Send image only
|
||||||
|
try:
|
||||||
file = discord.File(img_bytes, filename="gacha_result.png")
|
file = discord.File(img_bytes, filename="gacha_result.png")
|
||||||
try:
|
try:
|
||||||
await teaser.delete()
|
await teaser.delete()
|
||||||
except (discord.NotFound, discord.Forbidden):
|
except (discord.NotFound, discord.Forbidden):
|
||||||
pass
|
pass
|
||||||
await ctx.reply(file=file)
|
await ctx.reply(file=file)
|
||||||
|
except Exception as e:
|
||||||
|
log.exception("Failed to send result image")
|
||||||
|
await ctx.reply(f"Failed to send result: {e}")
|
||||||
|
|
||||||
@commands.command(name="spark")
|
@commands.command(name="spark")
|
||||||
async def spark(self, ctx: commands.Context, *, character_name: str = "") -> None:
|
async def spark(self, ctx: commands.Context, *, character_name: str = "") -> None:
|
||||||
|
|||||||
@@ -201,9 +201,15 @@ async def render_pull(
|
|||||||
_draw_footer(draw, spark_count)
|
_draw_footer(draw, spark_count)
|
||||||
|
|
||||||
# ── Fetch all portraits ─────────────────────────────────────────────
|
# ── Fetch all portraits ─────────────────────────────────────────────
|
||||||
async with aiohttp.ClientSession() as session:
|
timeout = aiohttp.ClientTimeout(total=60, connect=10)
|
||||||
|
async with aiohttp.ClientSession(timeout=timeout) as session:
|
||||||
portrait_tasks = [_fetch_portrait(session, p) for p in pulls]
|
portrait_tasks = [_fetch_portrait(session, p) for p in pulls]
|
||||||
portraits = await asyncio.gather(*portrait_tasks)
|
portraits = await asyncio.gather(*portrait_tasks, return_exceptions=True)
|
||||||
|
# Unwrap exceptions: failed fetches become None
|
||||||
|
for i, result in enumerate(portraits):
|
||||||
|
if isinstance(result, Exception):
|
||||||
|
log.warning("Portrait %d (%s) failed: %s", pulls[i]["Id"], pulls[i]["Name"], result)
|
||||||
|
portraits[i] = None
|
||||||
|
|
||||||
# ── Draw cards in grid ──────────────────────────────────────────────
|
# ── Draw cards in grid ──────────────────────────────────────────────
|
||||||
for idx, (student, portrait) in enumerate(zip(pulls, portraits)):
|
for idx, (student, portrait) in enumerate(zip(pulls, portraits)):
|
||||||
|
|||||||
Reference in new issue
Block a user