fix(slack): handle scans that produce no findings (#12229)

Co-authored-by: Juhef <117518034+juheff@users.noreply.github.com>
Co-authored-by: Daniel Barranquero <danielbo2001@gmail.com>
This commit is contained in:
Zuhef Ahmed
2026-08-27 14:03:33 +02:00
committed by GitHub
co-authored by Juhef Daniel Barranquero
parent ee64c17108
commit 2877c3d6c0
3 changed files with 58 additions and 2 deletions
@@ -0,0 +1 @@
CLI Slack integration (`--slack`) no longer fails when a scan produces no findings: the pass and fail percentages are guarded against a `findings_count` of 0, which previously raised `ZeroDivisionError` and sent `blocks=None` to Slack instead of the summary
+16 -2
View File
@@ -110,6 +110,20 @@ class Slack:
list: list of Slack message blocks.
"""
try:
# A scan can legitimately produce no findings, in which case
# `findings_count` is 0 and the percentages below would raise
# `ZeroDivisionError`.
findings_count = stats["findings_count"]
pass_percentage = (
round(stats["total_pass"] / findings_count * 100, 2)
if findings_count
else 0
)
fail_percentage = (
round(stats["total_fail"] / findings_count * 100, 2)
if findings_count
else 0
)
blocks = [
{
"type": "section",
@@ -128,7 +142,7 @@ class Slack:
"type": "section",
"text": {
"type": "mrkdwn",
"text": f"\n:white_check_mark: *{stats['total_pass']} Passed findings* ({round(stats['total_pass'] / stats['findings_count'] * 100, 2)}%)\n",
"text": f"\n:white_check_mark: *{stats['total_pass']} Passed findings* ({pass_percentage}%)\n",
},
},
{
@@ -148,7 +162,7 @@ class Slack:
"type": "section",
"text": {
"type": "mrkdwn",
"text": f"\n:x: *{stats['total_fail']} Failed findings* ({round(stats['total_fail'] / stats['findings_count'] * 100, 2)}%)\n ",
"text": f"\n:x: *{stats['total_fail']} Failed findings* ({fail_percentage}%)\n ",
},
},
{
+41
View File
@@ -205,6 +205,47 @@ class TestSlackIntegration:
},
]
def test_create_message_blocks_no_findings(self):
"""A scan that produced no findings must still build a valid message.
The pass/fail percentages divide by ``stats["findings_count"]``, which is
initialised to 0 in ``prowler/lib/outputs/outputs.py``. With no findings
that raises ``ZeroDivisionError``, the handler logs it and returns
``None``, and ``send()`` then passes ``blocks=None`` to
``chat_postMessage``.
"""
aws_provider = set_mocked_aws_provider()
slack = Slack(SLACK_TOKEN, SLACK_CHANNEL, aws_provider)
args = "--slack"
stats = {
"total_pass": 0,
"total_fail": 0,
"total_critical_severity_pass": 0,
"total_critical_severity_fail": 0,
"total_high_severity_fail": 0,
"total_high_severity_pass": 0,
"total_medium_severity_fail": 0,
"total_medium_severity_pass": 0,
"total_low_severity_fail": 0,
"total_low_severity_pass": 0,
"resources_count": 0,
"findings_count": 0,
}
blocks = slack.__create_message_blocks__(
f"AWS Account *{AWS_ACCOUNT_NUMBER}*", aws_logo, stats, args
)
assert blocks is not None, (
"__create_message_blocks__ returned None, so send() passes "
"blocks=None to chat_postMessage"
)
assert isinstance(blocks, list) and blocks
# The percentages must degrade to 0% rather than raising.
rendered = str(blocks)
assert "0 Passed findings* (0%)" in rendered
assert "0 Failed findings* (0%)" in rendered
def test_create_message_blocks_azure(self):
aws_provider = set_mocked_azure_provider()
slack = Slack(SLACK_TOKEN, SLACK_CHANNEL, aws_provider)