From 2d4a8f126ef761ad5706b92815af804e18c3eb4d Mon Sep 17 00:00:00 2001 From: David Jean Louis Date: Tue, 5 Mar 2024 10:10:02 +0100 Subject: [PATCH] Fixed #361: AttributeError in mailgun webhooks This fixes the case of delivery-status being None in the event data posted to mailgun webhook handler. See: #361 --- anymail/webhooks/mailgun.py | 8 ++--- tests/test_mailgun_webhooks.py | 57 ++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 4 deletions(-) diff --git a/anymail/webhooks/mailgun.py b/anymail/webhooks/mailgun.py index a9f4949d..233a737e 100644 --- a/anymail/webhooks/mailgun.py +++ b/anymail/webhooks/mailgun.py @@ -172,12 +172,12 @@ def esp_to_anymail_event(self, esp_event): try: delivery_status = event_data["delivery-status"] - except KeyError: - description = None - mta_response = None - else: + # if delivery_status is None, an AttributeError will be raised description = delivery_status.get("description") mta_response = delivery_status.get("message") + except (KeyError, AttributeError): + description = None + mta_response = None if "reason" in event_data: reject_reason = self.reject_reasons.get( diff --git a/tests/test_mailgun_webhooks.py b/tests/test_mailgun_webhooks.py index 946b0b56..5c95a542 100644 --- a/tests/test_mailgun_webhooks.py +++ b/tests/test_mailgun_webhooks.py @@ -630,6 +630,63 @@ def test_clicked_event(self): self.assertEqual(event.event_type, "clicked") self.assertEqual(event.click_url, "https://example.com/test") + def test_no_delivery_status(self): + raw_event = mailgun_sign_payload( + { + "signature": { + "timestamp": "1534108637", + "token": "651869375b9df3c98fc15c4889b102119add1235c38fc92824", + "signature": "...", + }, + "event-data": { + "tags": [], + "timestamp": 1534108637.153125, + "storage": { + "url": "https://sw.api.mailgun.net/v3/domains/" + "example.org/messages/eyJwI...", + "key": "eyJwI...", + }, + "recipient-domain": "example.com", + "id": "hTWCTD81RtiDN-...", + "campaigns": [], + "user-variables": {}, + "flags": { + "is-routed": False, + "is-authenticated": True, + "is-system-test": False, + "is-test-mode": False, + }, + "log-level": "info", + "envelope": { + "sending-ip": "333.123.123.200", + "sender": "test@example.org", + "transport": "smtp", + "targets": "recipient@example.com", + }, + "message": { + "headers": { + "to": "recipient@example.com", + "message-id": "20180812211713.1.DF5966851B4BAA99" + "@example.org", + "from": "test@example.org", + "subject": "Testing", + }, + "attachments": [], + "size": 809, + }, + "recipient": "recipient@example.com", + "event": "accepted", + "delivery-status": None, + }, + } + ) + response = self.client.post( + "/anymail/mailgun/tracking/", + data=json.dumps(raw_event), + content_type="application/json", + ) + self.assertEqual(response.status_code, 200) + @tag("mailgun") @override_settings(ANYMAIL_MAILGUN_WEBHOOK_SIGNING_KEY=TEST_WEBHOOK_SIGNING_KEY)