from functools import wraps from enum import Enum, auto from ..types import Message, Context, Response, CommandType class RollbotFailureException(BaseException): def __init__(self, failure): super().__init__() self.failure = failure class RollbotFailure(Enum): INVALID_COMMAND = auto() MISSING_SUBCOMMAND = auto() INVALID_SUBCOMMAND = auto() INVALID_ARGUMENTS = auto() SERVICE_DOWN = auto() PERMISSIONS = auto() INTERNAL_ERROR = auto() def get_debugging(self): debugging = {} reason = getattr(self, "reason", None) if reason is not None: debugging["explain"] = reason exception = getattr(self, "exception", None) if exception is not None: debugging["exception"] = exception return debugging def with_reason(self, reason): self.reason = reason return self def with_exception(self, exception): self.exception = exception return self def raise_exc(self): raise RollbotFailureException(self) def with_failure_handling(fn: CommandType) -> CommandType: @wraps(fn) async def wrapped(message: Message, context: Context): try: await fn() except RollbotFailureException as exc: # TODO handle errors more specifically await context.respond(Response.from_message(message, str(exc.failure))) return wrapped