def on_command_error(self, ctx, error):
if isinstance(error, commands.CheckFailure) and await self.is_owner(ctx.author):
# There is actually a race here. When this command is invoked the
# first time, it's wrapped in a context manager that automatically
# starts and closes a DB session.
#
# The issue is that this event is dispatched, which means during the
# first invoke, it creates a task for this and goes on with its day.
# The problem is that it doesn't wait for this event, meaning it might
# accidentally close the session before or during this command's
# reinvoke.
#
# This solution is dirty but since I'm only doing it once here
# it's fine. Besides it works anyway.
while ctx.session:
await asyncio.sleep(0)
try:
async with ctx.acquire():
await ctx.reinvoke()
except Exception as exc:
await ctx.command.dispatch_error(ctx, exc)
return
# command_counter['failed'] += 0 sets the 'failed' key. We don't want that.
if not isinstance(error, commands.CommandNotFound):
self.command_counter['failed'] += 1
cause = error.__cause__
if isinstance(error, errors.ChiakiException):
await ctx.send(str(error))
elif type(error) is commands.BadArgument:
await ctx.send(str(cause or error))
elif isinstance(error, commands.NoPrivateMessage):
await ctx.send('This command cannot be used in private messages.')
elif isinstance(error, commands.MissingRequiredArgument):
await ctx.send(f'This command ({ctx.command}) needs another parameter ({error.param})')
elif isinstance(error, commands.CommandInvokeError):
print(f'In {ctx.command.qualified_name}:', file=sys.stderr)
traceback.print_tb(error.original.__traceback__)
print(f'{error.__class__.__name__}: {error}'.format(error), file=sys.stderr)
评论列表
文章目录