Repository: Cog-Creators/Red-DiscordBot

Issue:
[V3 General] Long urban responses error out
# Command bugs

<!-- 
Did you find a bug with a command? Fill out the following:
-->

#### Command name

[p]urban

#### What cog is this command from?

General

#### What were you expecting to happen?

Expect the bot to return the results from the query.

#### What actually happened?

The command errors out.  The traceback indicates that the result message is too long (below).  I took a quick look at `general.py`, and [line 311](https://github.com/Cog-Creators/Red-DiscordBot/blob/79e5d2c9d7d152ff0e5df2e1b19e13075f2a7261/redbot/cogs/general/general.py#L311) is setting a value greater than the text limit of 2000 characters.  As well, [line 314](https://github.com/Cog-Creators/Red-DiscordBot/blob/79e5d2c9d7d152ff0e5df2e1b19e13075f2a7261/redbot/cogs/general/general.py#L314) seems to tack on more, rendering the previous check somewhat useless.
```
[2019-05-15 20:57:45] [ERROR] red: Exception in command 'urban'
Traceback (most recent call last):
  File "/home/injabie3/github/Rin/lib/python3.7/site-packages/discord.py-1.0.1-py3.7.egg/discord/ext/commands/core.py", line 63, in wrapped
    ret = await coro(*args, **kwargs)
  File "/home/injabie3/github/Rin/lib/python3.7/site-packages/Red_DiscordBot-3.1.1-py3.7.egg/redbot/cogs/general/general.py", line 327, in urban
    timeout=30,
  File "/home/injabie3/github/Rin/lib/python3.7/site-packages/Red_DiscordBot-3.1.1-py3.7.egg/redbot/core/utils/menus.py", line 71, in menu
    message = await ctx.send(current_page)
  File "/home/injabie3/github/Rin/lib/python3.7/site-packages/Red_DiscordBot-3.1.1-py3.7.egg/redbot/core/commands/context.py", line 63, in send
    return await super().send(content=content, **kwargs)
  File "/home/injabie3/github/Rin/lib/python3.7/site-packages/discord.py-1.0.1-py3.7.egg/discord/abc.py", line 776, in send
    data = await state.http.send_message(channel.id, content, tts=tts, embed=embed, nonce=nonce)
  File "/home/injabie3/github/Rin/lib/python3.7/site-packages/discord.py-1.0.1-py3.7.egg/discord/http.py", line 222, in request
    raise HTTPException(r, data)
discord.errors.HTTPException: BAD REQUEST (status code: 400): Invalid Form Body
In content: Must be 2000 or fewer in length.
```

Perhaps lowering the previous character limit above to something more conservative would be better?

#### How can we reproduce this issue?

1. Toggle embed results to off (e.g. `[p]embedset global`)
2. Run the following `[p]urban art student`

[V3 General] Long urban responses error out
# Command bugs

<!-- 
Did you find a bug with a command? Fill out the following:
-->

#### Command name

[p]urban

#### What cog is this command from?

General

#### What were you expecting to happen?

Expect the bot to return the results from the query.

#### What actually happened?

The command errors out.  The traceback indicates that the result message is too long (below).  I took a quick look at `general.py`, and [line 311](https://github.com/Cog-Creators/Red-DiscordBot/blob/79e5d2c9d7d152ff0e5df2e1b19e13075f2a7261/redbot/cogs/general/general.py#L311) is setting a value greater than the text limit of 2000 characters.  As well, [line 314](https://github.com/Cog-Creators/Red-DiscordBot/blob/79e5d2c9d7d152ff0e5df2e1b19e13075f2a7261/redbot/cogs/general/general.py#L314) seems to tack on more, rendering the previous check somewhat useless.
```
[2019-05-15 20:57:45] [ERROR] red: Exception in command 'urban'
Traceback (most recent call last):
  File "/home/injabie3/github/Rin/lib/python3.7/site-packages/discord.py-1.0.1-py3.7.egg/discord/ext/commands/core.py", line 63, in wrapped
    ret = await coro(*args, **kwargs)
  File "/home/injabie3/github/Rin/lib/python3.7/site-packages/Red_DiscordBot-3.1.1-py3.7.egg/redbot/cogs/general/general.py", line 327, in urban
    timeout=30,
  File "/home/injabie3/github/Rin/lib/python3.7/site-packages/Red_DiscordBot-3.1.1-py3.7.egg/redbot/core/utils/menus.py", line 71, in menu
    message = await ctx.send(current_page)
  File "/home/injabie3/github/Rin/lib/python3.7/site-packages/Red_DiscordBot-3.1.1-py3.7.egg/redbot/core/commands/context.py", line 63, in send
    return await super().send(content=content, **kwargs)
  File "/home/injabie3/github/Rin/lib/python3.7/site-packages/discord.py-1.0.1-py3.7.egg/discord/abc.py", line 776, in send
    data = await state.http.send_message(channel.id, content, tts=tts, embed=embed, nonce=nonce)
  File "/home/injabie3/github/Rin/lib/python3.7/site-packages/discord.py-1.0.1-py3.7.egg/discord/http.py", line 222, in request
    raise HTTPException(r, data)
discord.errors.HTTPException: BAD REQUEST (status code: 400): Invalid Form Body
In content: Must be 2000 or fewer in length.
```

Perhaps lowering the previous character limit above to something more conservative would be better?

#### How can we reproduce this issue?

1. Toggle embed results to off (e.g. `[p]embedset global`)
2. Run the following `[p]urban art student`



Discussion:

Resolving patch:
diff --git a/redbot/cogs/general/general.py b/redbot/cogs/general/general.py
--- a/redbot/cogs/general/general.py
+++ b/redbot/cogs/general/general.py
@@ -307,14 +307,17 @@ async def urban(self, ctx, *, word):
                 messages = []
                 for ud in data["list"]:
                     ud.setdefault("example", "N/A")
-                    description = _("{definition}\n\n**Example:** {example}").format(**ud)
-                    if len(description) > 2048:
-                        description = "{}...".format(description[:2045])
-
                     message = _(
                         "<{permalink}>\n {word} by {author}\n\n{description}\n\n"
                         "{thumbs_down} Down / {thumbs_up} Up, Powered by Urban Dictionary."
-                    ).format(word=ud.pop("word").capitalize(), description=description, **ud)
+                    ).format(word=ud.pop("word").capitalize(), description="{description}", **ud)
+                    max_desc_len = 2000 - len(message)
+
+                    description = _("{definition}\n\n**Example:** {example}").format(**ud)
+                    if len(description) > max_desc_len:
+                        description = "{}...".format(description[: max_desc_len - 3])
+
+                    message = message.format(description=description)
                     messages.append(message)
 
                 if messages is not None and len(messages) > 0:


Test patch: