better error handling (#92)

* safe logging of notifier failure to send

* added test
This commit is contained in:
Simone Robutti 2021-10-24 21:43:09 +02:00 committed by GitHub
parent e16dd19a7c
commit 41e82f5035
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 40 additions and 11 deletions

View File

@ -154,9 +154,12 @@ class AbstractCoordinator:
self.platforms = platforms
def send_to_all(self):
# TODO: failure to send should fail safely and write to a dedicated log
for platform in self.platforms:
platform.send(self.message)
try:
platform.send(self.message)
except Exception as e:
logger.critical(f"Notifier failed to send message:\n{self.message}")
logger.exception(e)
class AbstractNotifiersCoordinator(AbstractCoordinator):

View File

@ -1,3 +1,4 @@
import logging
from uuid import UUID
import pytest
@ -19,6 +20,17 @@ from mobilizon_reshare.publishers.coordinator import (
)
@pytest.fixture()
def failure_report(mock_publisher_invalid):
return EventPublicationReport(
status=PublicationStatus.FAILED,
reason="some failure",
publication=EventPublication(
publisher=mock_publisher_invalid, formatter=None, event=None, id=UUID(int=1)
),
)
@pytest.mark.parametrize(
"statuses, successful",
[
@ -136,18 +148,13 @@ async def test_publication_coordinator_run_failure_response(
@pytest.mark.asyncio
async def test_notifier_coordinator_publication_failed(mock_publisher_valid):
async def test_notifier_coordinator_publication_failed(
mock_publisher_valid, failure_report
):
mock_send = MagicMock()
mock_publisher_valid._send = mock_send
report = EventPublicationReport(
status=PublicationStatus.FAILED,
reason="some failure",
publication=EventPublication(
id=UUID(int=4), publisher=mock_publisher_valid, formatter=None, event=None
),
)
coordinator = PublicationFailureNotifiersCoordinator(
report, [mock_publisher_valid, mock_publisher_valid]
failure_report, [mock_publisher_valid, mock_publisher_valid]
)
coordinator.notify_failure()
@ -155,6 +162,25 @@ async def test_notifier_coordinator_publication_failed(mock_publisher_valid):
assert mock_send.call_count == 2
@pytest.mark.asyncio
async def test_notifier_coordinator_error(
failure_report, mock_publisher_invalid_response, caplog
):
mock_send = MagicMock()
mock_publisher_invalid_response._send = mock_send
coordinator = PublicationFailureNotifiersCoordinator(
failure_report,
[mock_publisher_invalid_response, mock_publisher_invalid_response],
)
with caplog.at_level(logging.CRITICAL):
coordinator.notify_failure()
assert "Notifier failed to send" in caplog.text
assert failure_report.get_failure_message() in caplog.text
# 4 = 2 reports * 2 notifiers
assert mock_send.call_count == 2
@pytest.mark.parametrize("num_publications", [2])
@pytest.mark.asyncio
async def test_recap_coordinator_run_success(