From 25d7d5409f8776d2b8c03aee6c1e82b798569b19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C4=93teris=20Caune?= Date: Thu, 19 Mar 2020 22:16:22 +0200 Subject: [PATCH] Telegram integration returns more detailed error messages --- CHANGELOG.md | 1 + hc/api/tests/test_notify.py | 10 ++++++++++ hc/api/transports.py | 32 ++++++++++++++++++-------------- 3 files changed, 29 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f26c842..aa4fb5ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ All notable changes to this project will be documented in this file. - Use Selectize.js for entering tags (#324) - Zulip integration (#202) - OpsGenie integration returns more detailed error messages +- Telegram integration returns more detailed error messages ### Bug Fixes - The "render_docs" command checks if markdown and pygments is installed (#329) diff --git a/hc/api/tests/test_notify.py b/hc/api/tests/test_notify.py index c6040eb6..694b8781 100644 --- a/hc/api/tests/test_notify.py +++ b/hc/api/tests/test_notify.py @@ -592,6 +592,16 @@ class NotifyTestCase(BaseTestCase): self.assertEqual(payload["chat_id"], 123) self.assertTrue("The check" in payload["text"]) + @patch("hc.api.transports.requests.request") + def test_telegram_returns_error(self, mock_post): + self._setup_data("telegram", json.dumps({"id": 123})) + mock_post.return_value.status_code = 400 + mock_post.return_value.json.return_value = {"description": "Hi"} + + self.channel.notify(self.check) + n = Notification.objects.first() + self.assertEqual(n.error, 'Received status code 400 with a message: "Hi"') + @patch("hc.api.transports.requests.request") def test_sms(self, mock_post): self._setup_data("sms", "+1234567890") diff --git a/hc/api/transports.py b/hc/api/transports.py index 53c1a67b..7519a80d 100644 --- a/hc/api/transports.py +++ b/hc/api/transports.py @@ -142,7 +142,9 @@ class Shell(Transport): class HttpTransport(Transport): @classmethod def get_error(cls, response): - return f"Received status code {response.status_code}" + # Override in subclasses: look for a specific error message in the + # response and return it. + return None @classmethod def _request(cls, method, url, **kwargs): @@ -156,7 +158,12 @@ class HttpTransport(Transport): r = requests.request(method, url, **options) if r.status_code not in (200, 201, 202, 204): - return cls.get_error(r) + m = cls.get_error(r) + if m: + return f'Received status code {r.status_code} with a message: "{m}"' + + return f"Received status code {r.status_code}" + except requests.exceptions.Timeout: # Well, we tried return "Connection timed out" @@ -261,15 +268,10 @@ class OpsGenie(HttpTransport): @classmethod def get_error(cls, response): try: - m = response.json().get("message") - if m: - code = response.status_code - return f'Received status code {code} with a message: "{m}"' + return response.json().get("message") except ValueError: pass - return super().get_error(response) - def notify(self, check): headers = { "Conent-Type": "application/json", @@ -441,6 +443,13 @@ class Discord(HttpTransport): class Telegram(HttpTransport): SM = "https://api.telegram.org/bot%s/sendMessage" % settings.TELEGRAM_TOKEN + @classmethod + def get_error(cls, response): + try: + return response.json().get("description") + except ValueError: + pass + @classmethod def send(cls, chat_id, text): return cls.post( @@ -560,15 +569,10 @@ class Zulip(HttpTransport): @classmethod def get_error(cls, response): try: - m = response.json().get("msg") - if m: - code = response.status_code - return f'Received status code {code} with a message: "{m}"' + return response.json().get("msg") except ValueError: pass - return super().get_error(response) - def notify(self, check): _, domain = self.channel.zulip_bot_email.split("@") url = "https://%s/api/v1/messages" % domain