aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRapptz <[email protected]>2016-01-09 14:00:17 -0500
committerRapptz <[email protected]>2016-01-09 14:00:17 -0500
commitad800e248ba70be04147aef093a7552a9f0aa586 (patch)
tree37ffb877903646d0a57dcdd077a4b11ec108bc81
parent[commands] Propagate invoked_with to subcommands. (diff)
downloaddiscord.py-ad800e248ba70be04147aef093a7552a9f0aa586.tar.xz
discord.py-ad800e248ba70be04147aef093a7552a9f0aa586.zip
[commands] Add local error handlers.
-rw-r--r--discord/ext/commands/core.py37
1 files changed, 37 insertions, 0 deletions
diff --git a/discord/ext/commands/core.py b/discord/ext/commands/core.py
index 5c755ed4..737df74d 100644
--- a/discord/ext/commands/core.py
+++ b/discord/ext/commands/core.py
@@ -97,6 +97,17 @@ class Command:
self.instance = None
self.parent = None
+ def handle_local_error(self, error, ctx):
+ try:
+ coro = self.on_error
+ except AttributeError:
+ return
+
+ if self.instance is not None:
+ discord.utils.create_task(coro(self.instance, error, ctx), loop=ctx.bot.loop)
+ else:
+ discord.utils.create_task(coro(error, ctx), loop=ctx.bot.loop)
+
def _receive_item(self, message, argument, regex, receiver, generator):
match = re.match(regex, argument)
result = None
@@ -224,6 +235,7 @@ class Command:
except StopIteration:
break
except CommandError as e:
+ self.handle_local_error(e, ctx)
ctx.bot.dispatch('command_error', e, ctx)
return False
return True
@@ -239,6 +251,7 @@ class Command:
if not check:
raise CheckFailure('The check functions for command {0.name} failed.'.format(self))
except CommandError as exc:
+ self.handle_local_error(exc, ctx)
ctx.bot.dispatch('command_error', exc, ctx)
return False
@@ -252,6 +265,30 @@ class Command:
if self._parse_arguments(ctx):
yield from self.callback(*ctx.args, **ctx.kwargs)
+ def error(self, coro):
+ """A decorator that registers a coroutine as a local error handler.
+
+ A local error handler is an :func:`on_command_error` event limited to
+ a single command. However, the :func:`on_command_error` is still
+ invoked afterwards as the catch-all.
+
+ Parameters
+ -----------
+ coro
+ The coroutine to register as the local error handler.
+
+ Raises
+ -------
+ discord.ClientException
+ The coroutine is not actually a coroutine.
+ """
+
+ if not asyncio.iscoroutinefunction(coro):
+ raise discord.ClientException('The error handler must be a coroutine.')
+
+ self.on_error = coro
+ return coro
+
class GroupMixin:
"""A mixin that implements common functionality for classes that behave
similar to :class:`Group` and are allowed to register commands.