From f1d26805d876aece0ba67ef96b126494bd0fb1a8 Mon Sep 17 00:00:00 2001 From: alejandrobailo Date: Tue, 21 Jul 2026 13:06:13 +0200 Subject: [PATCH] fix(api): expose failed Jira dispatch findings --- api/src/backend/tasks/jobs/integrations.py | 71 ++++++++++--------- .../backend/tasks/tests/test_integrations.py | 4 ++ 2 files changed, 42 insertions(+), 33 deletions(-) diff --git a/api/src/backend/tasks/jobs/integrations.py b/api/src/backend/tasks/jobs/integrations.py index c77ba22b7f..e92b52288a 100644 --- a/api/src/backend/tasks/jobs/integrations.py +++ b/api/src/backend/tasks/jobs/integrations.py @@ -487,36 +487,37 @@ def send_findings_to_jira( num_tickets_created = 0 error_messages = [] + failed_finding_ids = [] for finding_id in finding_ids: with rls_transaction(tenant_id): - finding_instance = ( - Finding.all_objects.select_related("scan__provider") - .prefetch_related("resources") - .get(id=finding_id) - ) - - # Extract resource information - resource = ( - finding_instance.resources.first() - if finding_instance.resources.exists() - else None - ) - resource_uid = resource.uid if resource else "" - resource_name = resource.name if resource else "" - resource_tags = {} - if resource and hasattr(resource, "tags"): - resource_tags = resource.get_tags(tenant_id) - - # Get region - region = resource.region if resource and resource.region else "" - - # Extract remediation information from check_metadata - check_metadata = finding_instance.check_metadata - remediation = check_metadata.get("remediation", {}) - recommendation = remediation.get("recommendation", {}) - remediation_code = remediation.get("code", {}) - try: + finding_instance = ( + Finding.all_objects.select_related("scan__provider") + .prefetch_related("resources") + .get(id=finding_id) + ) + + # Extract resource information + resource = ( + finding_instance.resources.first() + if finding_instance.resources.exists() + else None + ) + resource_uid = resource.uid if resource else "" + resource_name = resource.name if resource else "" + resource_tags = {} + if resource and hasattr(resource, "tags"): + resource_tags = resource.get_tags(tenant_id) + + # Get region + region = resource.region if resource and resource.region else "" + + # Extract remediation information from check_metadata + check_metadata = finding_instance.check_metadata + remediation = check_metadata.get("remediation", {}) + recommendation = remediation.get("recommendation", {}) + remediation_code = remediation.get("code", {}) + # Send the individual finding to Jira result = jira_integration.send_finding( check_id=finding_instance.check_id, @@ -546,18 +547,21 @@ def send_findings_to_jira( "Failed to send finding %s to Jira: %s", finding_id, error_message ) error_messages.append(error_message) + failed_finding_ids.append(finding_id) continue except Exception: logger.exception("Failed to send finding %s to Jira", finding_id) error_messages.append(JIRA_GENERIC_SEND_ERROR) + failed_finding_ids.append(finding_id) continue - if result: - num_tickets_created += 1 - else: - error_message = JIRA_GENERIC_SEND_ERROR - logger.error(error_message) - error_messages.append(error_message) + if result: + num_tickets_created += 1 + else: + error_message = JIRA_GENERIC_SEND_ERROR + logger.error(error_message) + error_messages.append(error_message) + failed_finding_ids.append(finding_id) result = { "created_count": num_tickets_created, @@ -565,5 +569,6 @@ def send_findings_to_jira( } if error_messages: result["error"] = "; ".join(dict.fromkeys(error_messages)) + result["failed_finding_ids"] = failed_finding_ids return result diff --git a/api/src/backend/tasks/tests/test_integrations.py b/api/src/backend/tasks/tests/test_integrations.py index bebb813feb..5d29fd5e00 100644 --- a/api/src/backend/tasks/tests/test_integrations.py +++ b/api/src/backend/tasks/tests/test_integrations.py @@ -1837,6 +1837,7 @@ class TestJiraIntegration: assert result == { "created_count": 2, "failed_count": 1, + "failed_finding_ids": ["finding-2"], "error": "Failed to create Jira issue.", } @@ -1903,6 +1904,7 @@ class TestJiraIntegration: assert result == { "created_count": 0, "failed_count": 1, + "failed_finding_ids": ["finding-1"], "error": error_message, } mock_logger.exception.assert_called_with( @@ -1971,6 +1973,7 @@ class TestJiraIntegration: assert result == { "created_count": 0, "failed_count": 1, + "failed_finding_ids": ["finding-1"], "error": error_message, } mock_logger.exception.assert_called_with( @@ -2035,6 +2038,7 @@ class TestJiraIntegration: assert result == { "created_count": 0, "failed_count": 1, + "failed_finding_ids": ["finding-1"], "error": "Failed to create Jira issue.", } assert "secret-value" not in result["error"]