Repository: Cog-Creators/Red-DiscordBot

Issue:
Warnings do not notify staff user has DMs closed or Blocked bot
# Other bugs

<!-- 
Did you find a bug with something other than a command? Fill out the following:
-->

#### What were you trying to do?

Warn a user with dms closed or blocked the bot

#### What were you expecting to happen?

Having bot say the user was blocked 

#### What actually happened?

Bock did not say user was blocked and unable to send direct message so we assumed their warning was sent to the user.

#### How can we reproduce this issue?

Block bot, send a test warn and see that it doesn't notify the staff member the user has their dms closed



Discussion:

Resolving patch:
diff --git a/redbot/cogs/warnings/warnings.py b/redbot/cogs/warnings/warnings.py
--- a/redbot/cogs/warnings/warnings.py
+++ b/redbot/cogs/warnings/warnings.py
@@ -361,19 +361,30 @@ async def warn(
 
         await warning_points_add_check(self.config, ctx, user, current_point_count)
         dm = await self.config.guild(ctx.guild).toggle_dm()
+        dm_failed = False
         if dm:
             em = discord.Embed(
                 title=_("Warning from {user}").format(user=ctx.author),
                 description=reason_type["description"],
             )
             em.add_field(name=_("Points"), value=str(reason_type["points"]))
-            with contextlib.suppress(discord.HTTPException):
+            try:
                 await user.send(
                     _("You have received a warning in {guild_name}.").format(
                         guild_name=ctx.guild.name
                     ),
                     embed=em,
                 )
+            except discord.HTTPException:
+                dm_failed = True
+
+        if dm_failed:
+            await ctx.send(
+                _(
+                    "A warning for {user} has been issued,"
+                    " but I wasn't able to send them a warn message."
+                ).format(user=user.mention)
+            )
 
         toggle_channel = await self.config.guild(guild).toggle_channel()
         if toggle_channel:
@@ -384,17 +395,22 @@ async def warn(
             em.add_field(name=_("Points"), value=str(reason_type["points"]))
             warn_channel = self.bot.get_channel(await self.config.guild(guild).warn_channel())
             if warn_channel:
-                channel = warn_channel
-                await ctx.tick()
-            else:
-                channel = ctx.channel
-            if channel.permissions_for(guild.me).send_messages:
-                with contextlib.suppress(discord.HTTPException):
-                    await channel.send(
+                if channel.permissions_for(guild.me).send_messages:
+                    with contextlib.suppress(discord.HTTPException):
+                        await channel.send(
+                            _("{user} has been warned.").format(user=user.mention), embed=em,
+                        )
+
+            if not dm_failed:
+                if warn_channel:
+                    await ctx.tick()
+                else:
+                    await ctx.send(
                         _("{user} has been warned.").format(user=user.mention), embed=em
                     )
         else:
-            await ctx.tick()
+            if not dm_failed:
+                await ctx.tick()
         try:
             reason_msg = _(
                 "{reason}\n\nUse `{prefix}unwarn {user} {message}` to remove this warning."


Test patch: