@@ -135,6 +135,8 @@ async def reports_status(self, ctx: commands.GuildContext):
135135 async def cmd_report (self , ctx : commands .GuildContext , * , message : str ):
136136 """Send a report to the mods.
137137
138+ ⚠️ `message` is required.
139+
138140 Example:
139141 - `[p]report <message>`
140142 """
@@ -148,29 +150,39 @@ async def cmd_report(self, ctx: commands.GuildContext, *, message: str):
148150
149151 @cmd_report .error
150152 async def on_cmd_report_error (self , ctx : commands .GuildContext , error ):
153+ if isinstance (error , commands .MissingRequiredArgument ):
154+ logger .debug (
155+ f"Emergency command missing required argument for { ctx .author .name } ({ ctx .author .id } ) in guild "
156+ f"{ ctx .guild .name } ({ ctx .guild .id } )"
157+ )
158+ await self ._send_cmd_error_response (
159+ ctx , error , f"Missing required argument in report command: `{ error .param .name } `."
160+ )
161+ return
162+
151163 if isinstance (error , commands .CommandOnCooldown ):
152164 logger .debug (
153165 f"Report command on cooldown for { ctx .author .name } ({ ctx .author .id } ) in guild "
154166 f"{ ctx .guild .name } ({ ctx .guild .id } ), ends in { error .retry_after :.1f} s"
155167 )
156- if ctx .interaction is not None and not ctx .interaction .response .is_done ():
157- await ctx .interaction .response .send_message (str (error ), ephemeral = True )
158- else :
159- await ctx .message .delete ()
160- await ctx .author .send (f"You are on cooldown. Try again in <t:{ error .retry_after } :R>" )
161- else :
162- logger .error (f"Unexpected error occurred: { error } " )
163- try :
164- await ctx .bot .send_to_owners (error )
165- except Exception as e :
166- logger .error (f"Failed to send error to owners: { e } " )
168+ retry_timestamp = int (error .retry_after + ctx .message .created_at .timestamp ())
169+ await self ._send_cmd_error_response (ctx , error , f"You are on cooldown. Try again in <t:{ retry_timestamp } :R>" )
170+ return
171+
172+ logger .error (f"Unexpected error occurred: { error } " )
173+ try :
174+ await ctx .bot .send_to_owners (error )
175+ except Exception as e :
176+ logger .error (f"Failed to send error to owners: { e } " )
167177
168178 @commands .hybrid_command ("emergency" )
169179 @commands .cooldown (1 , 30.0 , commands .BucketType .user )
170180 @commands .guild_only ()
171181 async def cmd_emergency (self , ctx : commands .GuildContext , * , message : str ):
172182 """Pings the mods with a high-priority report.
173183
184+ ⚠️ `message` is required.
185+
174186 Example:
175187 - `[p]emergency <message>`
176188 """
@@ -182,24 +194,32 @@ async def cmd_emergency(self, ctx: commands.GuildContext, *, message: str):
182194 logger .debug (f"Emergency report content length: { len (message )} characters" )
183195 await self .do_report (ctx .channel , ctx .message , message , True , ctx .interaction )
184196
185- @cmd_report .error
197+ @cmd_emergency .error
186198 async def on_cmd_emergency_error (self , ctx : commands .GuildContext , error ):
199+ if isinstance (error , commands .MissingRequiredArgument ):
200+ logger .debug (
201+ f"Emergency command missing required argument for { ctx .author .name } ({ ctx .author .id } ) in guild "
202+ f"{ ctx .guild .name } ({ ctx .guild .id } )"
203+ )
204+ await self ._send_cmd_error_response (
205+ ctx , error , f"Missing required argument in emergency command: `{ error .param .name } `."
206+ )
207+ return
208+
187209 if isinstance (error , commands .CommandOnCooldown ):
188210 logger .debug (
189211 f"Emergency command on cooldown for { ctx .author .name } ({ ctx .author .id } ) in guild "
190212 f"{ ctx .guild .name } ({ ctx .guild .id } ), ends in { error .retry_after :.1f} s"
191213 )
192- if ctx .interaction is not None and not ctx .interaction .response .is_done ():
193- await ctx .interaction .response .send_message (str (error ), ephemeral = True )
194- else :
195- await ctx .message .delete ()
196- await ctx .author .send (f"You are on cooldown. Try again in <t:{ error .retry_after } :R>" )
197- else :
198- logger .error (f"Unexpected error occurred: { error } " )
199- try :
200- await ctx .bot .send_to_owners (error )
201- except Exception as e :
202- logger .error (f"Failed to send error to owners: { e } " )
214+ retry_timestamp = int (error .retry_after + ctx .message .created_at .timestamp ())
215+ await self ._send_cmd_error_response (ctx , error , f"You are on cooldown. Try again in <t:{ retry_timestamp } :R>" )
216+ return
217+
218+ logger .error (f"Unexpected error occurred: { error } " )
219+ try :
220+ await ctx .bot .send_to_owners (error )
221+ except Exception as e :
222+ logger .error (f"Failed to send error to owners: { e } " )
203223
204224 async def get_log_channel (self , guild : discord .Guild ) -> TextLikeChannel | None :
205225 """Gets the log channel for the guild"""
@@ -285,7 +305,7 @@ async def send_emergency_report(self, log_channel: TextLikeChannel, embed: disco
285305
286306 async def do_report (
287307 self ,
288- channel : "discord.guild.GuildChannel | discord.Thread" ,
308+ channel : GuildChannelOrThread ,
289309 message : discord .Message ,
290310 report_body : str ,
291311 emergency : bool ,
@@ -335,7 +355,7 @@ async def do_report(
335355 await interaction .response .send_message (embed = report_reply , ephemeral = True )
336356
337357 # Else send a DM if DM confirmations are enabled
338- elif self .config .guild (channel .guild ).confirmations ():
358+ elif await self .config .guild (channel .guild ).confirmations ():
339359 logger .debug ("Sending confirmation via DM" )
340360 try :
341361 await message .author .send (embed = report_reply )
@@ -357,10 +377,10 @@ async def make_report_embed(
357377 )
358378
359379 if isinstance (channel , TextLikeChannel ):
360- last_msg = [ msg async for msg in channel .history (limit = 1 , before = message .created_at )][ 0 ] # noqa: RUF015
380+ last_msg = await anext ( channel .history (limit = 1 , before = message .created_at ), None )
361381 embed .add_field (name = "Context Region" , value = last_msg .jump_url if last_msg else "No messages found" )
362382 else :
363- embed .add_field (name = "Channel" , value = message . channel .mention ) # type: ignore
383+ embed .add_field (name = "Channel" , value = channel .mention )
364384
365385 embed .add_field (name = "Report Content" , value = escape (report_body or "<no message>" ))
366386 return embed
@@ -398,9 +418,7 @@ async def notify_truncation(
398418 except discord .Forbidden as exc :
399419 logger .error (f"Failed to notify { message .author .global_name } ({ message .author .id } ) about report truncation: { exc } " )
400420
401- async def notify_guild_owner_config_error (
402- self , channel : "discord.guild.GuildChannel | discord.Thread" , message : discord .Message , report_body : str
403- ):
421+ async def notify_guild_owner_config_error (self , channel : GuildChannelOrThread , message : discord .Message , report_body : str ):
404422 """Notify guild owner about misconfigured report log channel."""
405423 if channel .guild .owner is None :
406424 logger .warning (
@@ -433,3 +451,23 @@ async def notify_guild_owner_config_error(
433451 logger .info ("Successfully notified guild owner about config error" )
434452 except discord .Forbidden :
435453 logger .error ("Failed to send config error notification to guild owner - no DM permissions" )
454+
455+ async def _send_cmd_error_response (self , ctx : commands .GuildContext , error , response : str ):
456+ """
457+ Sends a command error response to the user.
458+
459+ If the context has an unresponded interaction, sends an ephemeral error message.
460+ Otherwise, deletes the original message and sends the response directly to the user.
461+
462+ Parameters:
463+ ctx (commands.GuildContext): The command context containing guild information
464+ error: The error object to be sent as a message
465+ response (str): The response message to send to the user
466+ Returns:
467+ None
468+ """
469+ if ctx .interaction is not None and not ctx .interaction .response .is_done ():
470+ await ctx .interaction .response .send_message (str (error ), ephemeral = True )
471+ else :
472+ await ctx .message .delete ()
473+ await ctx .author .send (response )
0 commit comments