From 4db2a79e0a67e8ee8a703914674bd897885ed5cb Mon Sep 17 00:00:00 2001 From: disqualifier Date: Mon, 6 Jul 2026 00:11:40 -0400 Subject: [PATCH] fix: cap Action/Actor embed field values to discord's 1024-char limit (dpylogger-8) The 1024-char cap + empty substitute only ever applied to the Log field. Action and Actor got no cap, so a long action/actor string (a real path - e.g. a long command invocation string as the action) triggers Discord's BASE_TYPE_MAX_LENGTH 400 on send; _send swallows that via log.exception and returns None, silently losing the Discord message while the stdlib mirror survives. Route all three fields through one _cap_field helper (single source for the 1024 constant) instead of duplicating the cap logic. Signed-off-by: disqualifier --- src/dpy_logger/dpy_logger.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/dpy_logger/dpy_logger.py b/src/dpy_logger/dpy_logger.py index 8dfccf5..85cfe20 100644 --- a/src/dpy_logger/dpy_logger.py +++ b/src/dpy_logger/dpy_logger.py @@ -54,6 +54,7 @@ DEFAULT_COLORS = { } DISCORD_CONTENT_LIMIT = 2000 +DISCORD_FIELD_VALUE_LIMIT = 1024 LEVEL_MAP = { "debug": logging.DEBUG, @@ -159,6 +160,13 @@ class DPYLogger: raise ValueError(f"[dpy_logger] configured channel {channel_id} is not a text channel") return channel + @staticmethod + def _cap_field(value: str) -> str: + """cap an embed field value to discord's 1024-char limit, truncating with an ellipsis""" + if len(value) > DISCORD_FIELD_VALUE_LIMIT: + return value[:DISCORD_FIELD_VALUE_LIMIT - 3] + "..." + return value + def build_embed(self, level, action, actor, details): """build the embed for a log call @@ -170,15 +178,13 @@ class DPYLogger: if self._embed_builder is not None: return self._embed_builder(self, level, action, actor, details) em = discord.Embed(color=self.colors[level]) + # discord 400s an empty or >1024-char field value; substitute + cap on every field if action is not None and str(action) != "": - em.add_field(name="Action", value=f"`{action}`", inline=True) + em.add_field(name="Action", value=self._cap_field(f"`{action}`"), inline=True) if actor is not None and str(actor) != "": - em.add_field(name="Actor", value=f"`{actor}`", inline=True) - # discord 400s an empty or >1024-char field value; substitute + cap + em.add_field(name="Actor", value=self._cap_field(f"`{actor}`"), inline=True) log_value = str(details) if details is not None and str(details) != "" else "(no message)" - if len(log_value) > 1024: - log_value = log_value[:1021] + "..." - em.add_field(name="Log", value=log_value, inline=False) + em.add_field(name="Log", value=self._cap_field(log_value), inline=False) em.timestamp = datetime.now(self.timezone) em.set_footer(text=f"{self.footer} Logging".strip(), icon_url=self.avatar) return em