diff --git a/src/dpy_logger/dpy_logger.py b/src/dpy_logger/dpy_logger.py index 85cfe20..0ee6d41 100644 --- a/src/dpy_logger/dpy_logger.py +++ b/src/dpy_logger/dpy_logger.py @@ -161,10 +161,12 @@ class DPYLogger: 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] + "..." + def _cap_field(value: str, reserve: int = 0) -> str: + """cap a value to discord's 1024-char field limit (less `reserve` chars for any wrapping + the caller adds around it, e.g. backticks), truncating with an ellipsis""" + limit = DISCORD_FIELD_VALUE_LIMIT - reserve + if len(value) > limit: + return value[:limit - 3] + "..." return value def build_embed(self, level, action, actor, details): @@ -178,11 +180,12 @@ 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 + # discord 400s an empty or >1024-char field value; cap then wrap so the closing + # backtick is never truncated off (cap the inner value, accounting for the 2 backticks) if action is not None and str(action) != "": - em.add_field(name="Action", value=self._cap_field(f"`{action}`"), inline=True) + em.add_field(name="Action", value=f"`{self._cap_field(str(action), reserve=2)}`", inline=True) if actor is not None and str(actor) != "": - em.add_field(name="Actor", value=self._cap_field(f"`{actor}`"), inline=True) + em.add_field(name="Actor", value=f"`{self._cap_field(str(actor), reserve=2)}`", inline=True) log_value = str(details) if details is not None and str(details) != "" else "(no message)" em.add_field(name="Log", value=self._cap_field(log_value), inline=False) em.timestamp = datetime.now(self.timezone)