🥅(backend) catch request timeout and Brevo contact addition errors

Handle unhandled exceptions to prevent UX impact. Marketing email operations
are optional and should not disrupt core functionality.

My first implementation was imperfect, raising error in sentry.
This commit is contained in:
lebaudantoine
2025-05-27 13:39:08 +02:00
committed by aleb_the_flash
parent 980117132f
commit 2a7d963f50
2 changed files with 27 additions and 1 deletions

View File

@@ -10,6 +10,7 @@ from django.core.exceptions import ImproperlyConfigured
from django.utils.module_loading import import_string
import brevo_python
import requests
logger = logging.getLogger(__name__)
@@ -120,7 +121,7 @@ class BrevoMarketingService:
try:
response = contact_api.create_contact(contact, **api_configurations)
except brevo_python.rest.ApiException as err:
except (brevo_python.rest.ApiException, requests.exceptions.ReadTimeout) as err:
logger.exception("Failed to create contact in Brevo")
raise ContactCreationError("Failed to create contact in Brevo") from err

View File

@@ -11,6 +11,7 @@ from django.core.exceptions import ImproperlyConfigured
import brevo_python
import pytest
import requests
from core.services.marketing import (
BrevoMarketingService,
@@ -133,6 +134,30 @@ def test_create_contact_api_error(mock_contact_api):
brevo_service.create_contact(valid_contact_data)
@mock.patch("brevo_python.ContactsApi")
def test_create_contact_timeout_error(mock_contact_api):
"""Test contact creation timeout error handling."""
mock_api = mock_contact_api.return_value
settings.BREVO_API_KEY = "test-api-key"
settings.BREVO_API_CONTACT_LIST_IDS = [1, 2, 3, 4]
settings.BREVO_API_CONTACT_ATTRIBUTES = {"source": "test"}
valid_contact_data = ContactData(
email="test@example.com",
attributes={"first_name": "Test"},
list_ids=[1, 2],
update_enabled=True,
)
brevo_service = BrevoMarketingService()
mock_api.create_contact.side_effect = requests.exceptions.ReadTimeout()
with pytest.raises(ContactCreationError, match="Failed to create contact in Brevo"):
brevo_service.create_contact(valid_contact_data)
@pytest.fixture
def clear_marketing_cache():
"""Clear marketing service cache between tests."""