Example #1
0
async def _subscription_handler_wrapper(
        col_q: Any, event_name: str,
        callback: Callable[[m.SubscriptionResult], Awaitable[Any]]) -> None:
    """Wrapper for a subscription callback providing:
    - Basic error handling and logging
    - Create a task for each incoming message
    """
    logger.debug(f"Subscription handler for {event_name} started")
    while True:
        try:
            event = await col_q.get()
            if event['type'] == 'changed':
                result = m.SubscriptionResult(**event['fields'])
                if event_name == result.eventName:
                    callback_coro = _exception_wrapper(event_name,
                                                       callback(result))
                    # Offload into task such that new messages can be handled directly
                    asyncio.create_task(callback_coro)
        except asyncio.CancelledError:
            logger.debug(f"Subscription handler for {event_name} stopped")
            return
        except Exception:
            logger.exception(
                f"Exception in subscription handler for {event_name}.")
            sentry.exception()
Example #2
0
def send_kafka_message(options: List[pollutil.PollOption], botname: str) -> None:
    try:
        kafkaproducer = RocketchatMensaProducer()

        opts = [(o.text, [u for u in o.users if u != botname]) for o in options]
        kafkaproducer.sendV1(opts)
        kafkaproducer.close()
    except Exception as e:
        logger.error(f"{type(e).__name__}: {e}", exc_info=True)
        sentry.exception()
Example #3
0
async def _exception_wrapper(event_name: str,
                             callback: Awaitable[None]) -> None:
    """Wrapper for coroutines to catch and log exceptions"""
    try:
        await callback
    except asyncio.CancelledError:
        logger.info(f'Subscription callback for {event_name} canceled')
    except Exception:
        sentry.exception()
        logger.exception(f'Caught exception in subscription callback')
Example #4
0
async def main() -> None:
    masterbot = await setup_bot()

    while True:
        try:
            async with masterbot:
                logging.info(f'{c.BOTNAME} is ready')
                await masterbot.ddp.disconnection()
            # If run terminates without exception end the while true loop
            break
        except (RocketConnectionException, requests.exceptions.SSLError,
                JSONDecodeError):
            logging.error("Failed to connect. Retry in 60s")
            time.sleep(60)
        except Exception as e:
            logging.error(f"{type(e).__name__}: {e}", exc_info=True)
            sentry.exception()
Example #5
0
    async def handle(self, command: str, args: str,
                     message: m.Message) -> None:
        """Handle the incoming message
        """
        event = await self._check_running_tasks(command)
        try:
            if command == 'poll':
                try:
                    await self.create_poll(args, message)
                except exp.RocketBotPollException as e:
                    await self.master.ddp.send_message(message.roomid, str(e))
                    sentry.exception()

            if command == 'poll_push':
                match = re.match(r'\s*#(\S+)', args)
                if not match:
                    await self.master.ddp.send_message(
                        message.roomid, "Please specify a room")
                    return

                room_name = match.groups()[0]

                if message.roomid not in self.pollmanager.polls.last_active_by_roomid:
                    await self.master.ddp.send_message(
                        message.roomid, "Please create a poll first")
                    return

                poll = self.pollmanager.polls.last_active_by_roomid[
                    message.roomid]
                roomref = [r for r in message.channels if r.name == room_name]
                if len(roomref) != 0:
                    try:
                        await self.pollmanager.push(poll, roomref[0]._id)
                    except exp.RocketBotPollException as e:
                        await self.master.ddp.send_message(
                            message.roomid,
                            f"{e} - Am I part of that channel?")
                        sentry.exception()
                    return
                await self.master.ddp.send_message(
                    message.roomid, "No roomref found. Is this a valid room?")
        finally:
            # Set the event will trigger the next queued handle call
            event.set()