diff --git a/vulnerabilities/pipes/advisory.py b/vulnerabilities/pipes/advisory.py index 9d242c01f..7a26ff2b1 100644 --- a/vulnerabilities/pipes/advisory.py +++ b/vulnerabilities/pipes/advisory.py @@ -337,9 +337,10 @@ def insert_advisory_v2( if values: getattr(advisory_obj, field_name).add(*values) - except Advisory.MultipleObjectsReturned: + except AdvisoryV2.MultipleObjectsReturned: logger( - f"Multiple Advisories returned: unique_content_id: {content_id}, url: {advisory.url}, advisory: {advisory!r}" + f"Multiple Advisories returned: unique_content_id: {content_id}, url: {advisory.url}, advisory: {advisory!r}", + level=logging.ERROR, ) raise except Exception as e: diff --git a/vulnerabilities/tests/pipes/test_advisory.py b/vulnerabilities/tests/pipes/test_advisory.py index 8710b2ea4..d1a456d65 100644 --- a/vulnerabilities/tests/pipes/test_advisory.py +++ b/vulnerabilities/tests/pipes/test_advisory.py @@ -257,3 +257,46 @@ def test_get_or_create_advisory_commit(advisory_commit): assert isinstance(commit, PackageCommitPatch) assert commit.commit_hash in [c.commit_hash for c in advisory_commit] assert commit.vcs_url in [c.vcs_url for c in advisory_commit] + + +@pytest.mark.django_db +def test_insert_advisory_v2_handles_multiple_objects_returned(): + """ + Test that insert_advisory_v2 correctly handles AdvisoryV2.MultipleObjectsReturned + exception when duplicate advisory records exist. + """ + from unittest.mock import MagicMock + from unittest.mock import patch + from vulnerabilities.models import AdvisoryV2 + from vulnerabilities.pipes.advisory import insert_advisory_v2 + + advisory_data = AdvisoryData( + summary="Test advisory for exception handling", + affected_packages=[ + AffectedPackage( + package=PackageURL(type="pypi", name="test-package"), + affected_version_range=VersionRange.from_string("vers:pypi/>=1.0.0|<=2.0.0"), + ) + ], + references=[Reference(url="https://example.com/advisory/test")], + date_published=timezone.now(), + url="https://test-advisory.example.com/duplicated", + advisory_id="TEST-2024-001", + ) + + mock_logger = MagicMock() + + with patch.object(AdvisoryV2.objects, "get_or_create") as mock_get_or_create: + mock_get_or_create.side_effect = AdvisoryV2.MultipleObjectsReturned() + + with pytest.raises(AdvisoryV2.MultipleObjectsReturned): + insert_advisory_v2( + advisory=advisory_data, + pipeline_id="test_pipeline", + logger=mock_logger, + ) + + mock_logger.assert_called_once() + args, _ = mock_logger.call_args + assert "Multiple Advisories returned" in args[0] +