def send_failure_alert(printer, is_warning=True, print_paused=False): LOGGER.info( f'Printer {printer.user.id} {"smells fishy" if is_warning else "is probably failing"}. Sending Alerts' ) if not printer.current_print: LOGGER.warn( f'Trying to alert on printer without current print. printer_id: {printer.id}' ) return rotated_jpg_url = save_print_snapshot( printer, last_pic_of_print(printer.current_print, 'tagged'), f'snapshots/{printer.id}/{printer.current_print.id}/{str(timezone.now().timestamp())}_rotated.jpg', rotated=True, to_long_term_storage=False) # Calls wrapped in individual try/except because anyone of them could fail, and we still want the flow to continue try: mobile_notifications.send_failure_alert(printer, rotated_jpg_url, is_warning, print_paused) except: sentryClient.captureException() try: if printer.user.alert_by_email: send_failure_alert_email(printer, rotated_jpg_url, is_warning, print_paused) except: sentryClient.captureException() try: send_failure_alert_pushbullet(printer, rotated_jpg_url, is_warning, print_paused) except: sentryClient.captureException() try: send_failure_alert_pushover(printer, rotated_jpg_url, is_warning, print_paused) except: sentryClient.captureException() try: send_failure_alert_telegram(printer, rotated_jpg_url, is_warning, print_paused) except: sentryClient.captureException() try: if printer.user.is_pro and printer.user.alert_by_sms: send_failure_alert_sms(printer, is_warning, print_paused) except: sentryClient.captureException() try: if printer.user.is_pro: send_failure_alert_slack(printer, rotated_jpg_url, is_warning, print_paused) except: sentryClient.captureException() try: send_failure_alert_discord(printer, rotated_jpg_url, is_warning, print_paused) except: capture_exception()
def send_failure_alerts( self, is_warning: bool, print_paused: bool, printer: Printer, print_: Print, img_url: str, extra_context: Optional[Dict] = None, plugin_names: Tuple[str, ...] = (), fail_silently: bool = True, ) -> None: try: mobile_notifications.send_failure_alert(printer, img_url, is_warning, print_paused) except Exception: capture_exception() if plugin_names: names = list(set(self.notification_plugin_names()) & set(plugin_names)) else: names = self.notification_plugin_names() # select matching, enabled & configured nsettings = list(NotificationSetting.objects.filter( user_id=printer.user_id, enabled=True, name__in=names, notify_on_failure_alert=True )) if not nsettings: LOGGER.debug("no matching NotificationSetting objects, ignoring failure alert") return user_ctx = self.get_user_context(printer.user) printer_ctx = self.get_printer_context(printer) print_ctx = self.get_print_context(print_) for nsetting in nsettings: LOGGER.debug(f'forwarding failure alert to plugin "{nsetting.name}" (pk: {nsetting.pk})') try: plugin = self.notification_plugin_by_name(nsetting.name) if not plugin: continue context = FailureAlertContext( config=nsetting.config, user=user_ctx, printer=printer_ctx, print=print_ctx, is_warning=is_warning, print_paused=print_paused, extra_context=extra_context, img_url=img_url, ) self._send_failure_alert(nsetting=nsetting, context=context) except NotImplementedError: pass except Exception: if fail_silently: LOGGER.exception('send_failure_alert plugin error') capture_exception() else: raise