diff --git a/vulnerabilities/models.py b/vulnerabilities/models.py index 5f0cfa4ea..fed67fe42 100644 --- a/vulnerabilities/models.py +++ b/vulnerabilities/models.py @@ -2926,7 +2926,9 @@ def to_dict(self): class AdvisoryV2QuerySet(BaseQuerySet): def latest_for_avid(self, avid: str): - return self.get(avid=avid, is_latest=True) + # Return None when there is no advisory for this avid: the detail + # views rely on this to raise an Http404 instead of a server error. + return self.filter(avid=avid, is_latest=True).first() def latest_per_avid(self): return self.filter(is_latest=True) diff --git a/vulnerabilities/tests/test_view.py b/vulnerabilities/tests/test_view.py index bcee104ac..95cfa42a7 100644 --- a/vulnerabilities/tests/test_view.py +++ b/vulnerabilities/tests/test_view.py @@ -379,3 +379,22 @@ def test_throttle_after_15_requests(self): HTTP_USER_AGENT="test-agent", ) assert response.status_code == 429 + + +class AdvisoryDetailNotFoundTestCase(TestCase): + def setUp(self): + # bypass the altcha bot protection middleware + import time + + session = self.client.session + session["altcha_verified_at"] = time.time() + session.save() + + def test_unknown_advisory_avid_returns_404_not_500(self): + # https://github.com/aboutcode-org/vulnerablecode/issues/2396 + response = self.client.get("/advisories/pysec/PYSEC-3000-0") + self.assertEqual(404, response.status_code) + + def test_unknown_advisory_packages_avid_returns_404_not_500(self): + response = self.client.get("/advisories/packages/pysec/PYSEC-3000-0") + self.assertEqual(404, response.status_code)