aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar kwzrd <[email protected]>2020-09-29 10:01:25 +0200
committerGravatar GitHub <[email protected]>2020-09-29 10:01:25 +0200
commit403bb4940817002c75099a47eddfe48c5b279a76 (patch)
tree542c6d295139ea5f28731ffc382abd64518160cc
parentMerge remote-tracking branch 'origin/master' into master (diff)
parentIncidents: reduce timeout log to info level (diff)
PR #1191 Verification: broaden 50_007 error handling
-rw-r--r--bot/exts/moderation/incidents.py2
-rw-r--r--bot/exts/moderation/verification.py39
2 files changed, 30 insertions, 11 deletions
diff --git a/bot/exts/moderation/incidents.py b/bot/exts/moderation/incidents.py
index 31be48a43..0e479d33f 100644
--- a/bot/exts/moderation/incidents.py
+++ b/bot/exts/moderation/incidents.py
@@ -319,7 +319,7 @@ class Incidents(Cog):
try:
await confirmation_task
except asyncio.TimeoutError:
- log.warning(f"Did not receive incident deletion confirmation within {timeout} seconds!")
+ log.info(f"Did not receive incident deletion confirmation within {timeout} seconds!")
else:
log.trace("Deletion was confirmed")
diff --git a/bot/exts/moderation/verification.py b/bot/exts/moderation/verification.py
index e9ab2c816..206556483 100644
--- a/bot/exts/moderation/verification.py
+++ b/bot/exts/moderation/verification.py
@@ -109,6 +109,25 @@ def is_verified(member: discord.Member) -> bool:
return len(set(member.roles) - unverified_roles) > 0
+async def safe_dm(coro: t.Coroutine) -> None:
+ """
+ Execute `coro` ignoring disabled DM warnings.
+
+ The 50_0007 error code indicates that the target user does not accept DMs.
+ As it turns out, this error code can appear on both 400 and 403 statuses,
+ we therefore catch any Discord exception.
+
+ If the request fails on any other error code, the exception propagates,
+ and must be handled by the caller.
+ """
+ try:
+ await coro
+ except discord.HTTPException as discord_exc:
+ log.trace(f"DM dispatch failed on status {discord_exc.status} with code: {discord_exc.code}")
+ if discord_exc.code != 50_007: # If any reason other than disabled DMs
+ raise
+
+
class Verification(Cog):
"""
User verification and role management.
@@ -330,11 +349,9 @@ class Verification(Cog):
async def kick_request(member: discord.Member) -> None:
"""Send `KICKED_MESSAGE` to `member` and kick them from the guild."""
try:
- await member.send(KICKED_MESSAGE)
- except discord.Forbidden as exc_403:
- log.trace(f"DM dispatch failed on 403 error with code: {exc_403.code}")
- if exc_403.code != 50_007: # 403 raised for any other reason than disabled DMs
- raise StopExecution(reason=exc_403)
+ await safe_dm(member.send(KICKED_MESSAGE)) # Suppress disabled DMs
+ except discord.HTTPException as suspicious_exception:
+ raise StopExecution(reason=suspicious_exception)
await member.kick(reason=f"User has not verified in {constants.Verification.kicked_after} days")
n_kicked = await self._send_requests(members, kick_request, Limit(batch_size=2, sleep_secs=1))
@@ -503,8 +520,10 @@ class Verification(Cog):
return # Only listen for PyDis events
log.trace(f"Sending on join message to new member: {member.id}")
- with suppress(discord.Forbidden):
- await member.send(ON_JOIN_MESSAGE)
+ try:
+ await safe_dm(member.send(ON_JOIN_MESSAGE))
+ except discord.HTTPException:
+ log.exception("DM dispatch failed on unexpected error code")
@Cog.listener()
async def on_message(self, message: discord.Message) -> None:
@@ -671,9 +690,9 @@ class Verification(Cog):
await ctx.author.remove_roles(discord.Object(constants.Roles.unverified))
try:
- await ctx.author.send(VERIFIED_MESSAGE)
- except discord.Forbidden:
- log.info(f"Sending welcome message failed for {ctx.author}.")
+ await safe_dm(ctx.author.send(VERIFIED_MESSAGE))
+ except discord.HTTPException:
+ log.exception(f"Sending welcome message failed for {ctx.author}.")
finally:
log.trace(f"Deleting accept message by {ctx.author}.")
with suppress(discord.NotFound):