We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Error in slack_notification Action
Hi Guys,
I have 3 pipelines with great expectations, but one pipeline started to give some errors:

`Error running action with name notify_slack
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/great_expectations/validation_operators/validation_operators.py", line 384, in _run_actions
    payload=batch_actions_results,
  File "/usr/local/lib/python3.7/site-packages/great_expectations/validation_operators/actions.py", line 55, in run
    **kwargs,
  File "/usr/local/lib/python3.7/site-packages/great_expectations/validation_operators/actions.py", line 170, in _run
    validation_result_suite, data_docs_pages, self.notify_with
  File "/usr/local/lib/python3.7/site-packages/great_expectations/render/renderer/slack_renderer.py", line 101, in render
    report_element = self._get_report_element(docs_link)
  File "/usr/local/lib/python3.7/site-packages/great_expectations/render/renderer/slack_renderer.py", line 155, in _get_report_element
    if "file:///" in docs_link:
TypeError: argument of type 'NoneType' is not iterable
Traceback (most recent call last):
  File "fact_demand_coverage_datalake_datasets_job.py", line 90, in <module>
    expectation_suite=expectation_suite_name_for_validations
  File "/mnt1/yarn/usercache/hadoop/appcache/application_1603978914184_5458/container_1603978914184_5458_01_000001/data_quality.zip/data_quality/ge_validation.py", line 174, in validate
  File "/usr/local/lib/python3.7/site-packages/great_expectations/core/usage_statistics/usage_statistics.py", line 257, in usage_statistics_wrapped_method
    result = func(*args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/great_expectations/data_context/data_context.py", line 1022, in run_validation_operator
    **kwargs,
  File "/usr/local/lib/python3.7/site-packages/great_expectations/validation_operators/validation_operators.py", line 334, in run
    run_id,
  File "/usr/local/lib/python3.7/site-packages/great_expectations/validation_operators/validation_operators.py", line 399, in _run_actions
    raise e
  File "/usr/local/lib/python3.7/site-packages/great_expectations/validation_operators/validation_operators.py", line 384, in _run_actions
    payload=batch_actions_results,
  File "/usr/local/lib/python3.7/site-packages/great_expectations/validation_operators/actions.py", line 55, in run
    **kwargs,
  File "/usr/local/lib/python3.7/site-packages/great_expectations/validation_operators/actions.py", line 170, in _run
    validation_result_suite, data_docs_pages, self.notify_with
  File "/usr/local/lib/python3.7/site-packages/great_expectations/render/renderer/slack_renderer.py", line 101, in render
    report_element = self._get_report_element(docs_link)
  File "/usr/local/lib/python3.7/site-packages/great_expectations/render/renderer/slack_renderer.py", line 155, in _get_report_element
    if "file:///" in docs_link:
TypeError: argument of type 'NoneType' is not iterable`

The stranger thing with this error, the error doesn't happen every day, for example yesterday it worked fine.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `great_expectations/render/renderer/slack_renderer.py`
Content:
```
1 import logging
2 
3 from great_expectations.exceptions import InvalidKeyError
4 
5 logger = logging.getLogger(__name__)
6 
7 from ...core.id_dict import BatchKwargs
8 from .renderer import Renderer
9 
10 
11 class SlackRenderer(Renderer):
12     def __init__(self):
13         super().__init__()
14 
15     def render(
16         self, validation_result=None, data_docs_pages=None, notify_with=None,
17     ):
18         default_text = (
19             "No validation occurred. Please ensure you passed a validation_result."
20         )
21         status = "Failed :x:"
22 
23         title_block = {
24             "type": "section",
25             "text": {"type": "mrkdwn", "text": default_text,},
26         }
27 
28         query = {
29             "blocks": [title_block],
30             # this abbreviated root level "text" will show up in the notification and not the message
31             "text": default_text,
32         }
33 
34         if validation_result:
35             expectation_suite_name = validation_result.meta.get(
36                 "expectation_suite_name", "__no_expectation_suite_name__"
37             )
38 
39             if "batch_kwargs" in validation_result.meta:
40                 data_asset_name = validation_result.meta["batch_kwargs"].get(
41                     "data_asset_name", "__no_data_asset_name__"
42                 )
43             else:
44                 data_asset_name = "__no_data_asset_name__"
45 
46             n_checks_succeeded = validation_result.statistics["successful_expectations"]
47             n_checks = validation_result.statistics["evaluated_expectations"]
48             run_id = validation_result.meta.get("run_id", "__no_run_id__")
49             batch_id = BatchKwargs(
50                 validation_result.meta.get("batch_kwargs", {})
51             ).to_id()
52             check_details_text = (
53                 f"*{n_checks_succeeded}* of *{n_checks}* expectations were met"
54             )
55 
56             if validation_result.success:
57                 status = "Success :tada:"
58 
59             summary_text = f"""*Batch Validation Status*: {status}
60 *Expectation suite name*: `{expectation_suite_name}`
61 *Data asset name*: `{data_asset_name}`
62 *Run ID*: `{run_id}`
63 *Batch ID*: `{batch_id}`
64 *Summary*: {check_details_text}"""
65             query["blocks"][0]["text"]["text"] = summary_text
66             # this abbreviated root level "text" will show up in the notification and not the message
67             query["text"] = f"{expectation_suite_name}: {status}"
68 
69             if data_docs_pages:
70                 if notify_with is not None:
71                     for docs_link_key in notify_with:
72                         if docs_link_key in data_docs_pages.keys():
73                             docs_link = data_docs_pages[docs_link_key]
74                             report_element = self._get_report_element(docs_link)
75                         else:
76                             logger.critical(
77                                 f"*ERROR*: Slack is trying to provide a link to the following DataDocs: `{str(docs_link_key)}`, but it is not configured under `data_docs_sites` in the `great_expectations.yml`\n"
78                             )
79                             report_element = {
80                                 "type": "section",
81                                 "text": {
82                                     "type": "mrkdwn",
83                                     "text": f"*ERROR*: Slack is trying to provide a link to the following DataDocs: `{str(docs_link_key)}`, but it is not configured under `data_docs_sites` in the `great_expectations.yml`\n",
84                                 },
85                             }
86                         if report_element:
87                             query["blocks"].append(report_element)
88                 else:
89                     for docs_link_key in data_docs_pages.keys():
90                         if docs_link_key == "class":
91                             continue
92                         docs_link = data_docs_pages[docs_link_key]
93                         report_element = self._get_report_element(docs_link)
94                         if report_element:
95                             query["blocks"].append(report_element)
96 
97             if "result_reference" in validation_result.meta:
98                 result_reference = validation_result.meta["result_reference"]
99                 report_element = {
100                     "type": "section",
101                     "text": {
102                         "type": "mrkdwn",
103                         "text": f"- *Validation Report*: {result_reference}",
104                     },
105                 }
106                 query["blocks"].append(report_element)
107 
108             if "dataset_reference" in validation_result.meta:
109                 dataset_reference = validation_result.meta["dataset_reference"]
110                 dataset_element = {
111                     "type": "section",
112                     "text": {
113                         "type": "mrkdwn",
114                         "text": f"- *Validation data asset*: {dataset_reference}",
115                     },
116                 }
117                 query["blocks"].append(dataset_element)
118 
119         custom_blocks = self._custom_blocks(evr=validation_result)
120         if custom_blocks:
121             query["blocks"].append(custom_blocks)
122 
123         documentation_url = "https://docs.greatexpectations.io/en/latest/guides/tutorials/getting_started/set_up_data_docs.html"
124         footer_section = {
125             "type": "context",
126             "elements": [
127                 {
128                     "type": "mrkdwn",
129                     "text": f"Learn how to review validation results in Data Docs: {documentation_url}",
130                 }
131             ],
132         }
133 
134         divider_block = {"type": "divider"}
135         query["blocks"].append(divider_block)
136         query["blocks"].append(footer_section)
137         return query
138 
139     def _custom_blocks(self, evr):
140         return None
141 
142     def _get_report_element(self, docs_link):
143         if docs_link is None:
144             logger.warn("No docs link found. Skipping data docs link in slack message.")
145             return
146 
147         if "file://" in docs_link:
148             # handle special case since Slack does not render these links
149             report_element = {
150                 "type": "section",
151                 "text": {
152                     "type": "mrkdwn",
153                     "text": f"*DataDocs* can be found here: `{docs_link}` \n (Please copy and paste link into a browser to view)\n",
154                 },
155             }
156         else:
157             report_element = {
158                 "type": "section",
159                 "text": {
160                     "type": "mrkdwn",
161                     "text": f"*DataDocs* can be found here: <{docs_link}|{docs_link}>",
162                 },
163             }
164         return report_element
165
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/great_expectations/render/renderer/slack_renderer.py b/great_expectations/render/renderer/slack_renderer.py
--- a/great_expectations/render/renderer/slack_renderer.py
+++ b/great_expectations/render/renderer/slack_renderer.py
@@ -116,10 +116,6 @@
                 }
                 query["blocks"].append(dataset_element)
 
-        custom_blocks = self._custom_blocks(evr=validation_result)
-        if custom_blocks:
-            query["blocks"].append(custom_blocks)
-
         documentation_url = "https://docs.greatexpectations.io/en/latest/guides/tutorials/getting_started/set_up_data_docs.html"
         footer_section = {
             "type": "context",
@@ -136,29 +132,36 @@
         query["blocks"].append(footer_section)
         return query
 
-    def _custom_blocks(self, evr):
-        return None
-
     def _get_report_element(self, docs_link):
-        if docs_link is None:
-            logger.warn("No docs link found. Skipping data docs link in slack message.")
-            return
-
-        if "file://" in docs_link:
-            # handle special case since Slack does not render these links
-            report_element = {
-                "type": "section",
-                "text": {
-                    "type": "mrkdwn",
-                    "text": f"*DataDocs* can be found here: `{docs_link}` \n (Please copy and paste link into a browser to view)\n",
-                },
-            }
+        report_element = None
+        if docs_link:
+            try:
+                if "file://" in docs_link:
+                    # handle special case since Slack does not render these links
+                    report_element = {
+                        "type": "section",
+                        "text": {
+                            "type": "mrkdwn",
+                            "text": f"*DataDocs* can be found here: `{docs_link}` \n (Please copy and paste link into a browser to view)\n",
+                        },
+                    }
+                else:
+                    report_element = {
+                        "type": "section",
+                        "text": {
+                            "type": "mrkdwn",
+                            "text": f"*DataDocs* can be found here: <{docs_link}|{docs_link}>",
+                        },
+                    }
+            except Exception as e:
+                logger.warning(
+                    f"""SlackRenderer had a problem with generating the docs link.
+                    link used to generate the docs link is: {docs_link} and is of type: {type(docs_link)}.
+                    Error: {e}"""
+                )
+                return
         else:
-            report_element = {
-                "type": "section",
-                "text": {
-                    "type": "mrkdwn",
-                    "text": f"*DataDocs* can be found here: <{docs_link}|{docs_link}>",
-                },
-            }
+            logger.warning(
+                "No docs link found. Skipping data docs link in Slack message."
+            )
         return report_element

{"golden_diff": "diff --git a/great_expectations/render/renderer/slack_renderer.py b/great_expectations/render/renderer/slack_renderer.py\n--- a/great_expectations/render/renderer/slack_renderer.py\n+++ b/great_expectations/render/renderer/slack_renderer.py\n@@ -116,10 +116,6 @@\n                 }\n                 query[\"blocks\"].append(dataset_element)\n \n-        custom_blocks = self._custom_blocks(evr=validation_result)\n-        if custom_blocks:\n-            query[\"blocks\"].append(custom_blocks)\n-\n         documentation_url = \"https://docs.greatexpectations.io/en/latest/guides/tutorials/getting_started/set_up_data_docs.html\"\n         footer_section = {\n             \"type\": \"context\",\n@@ -136,29 +132,36 @@\n         query[\"blocks\"].append(footer_section)\n         return query\n \n-    def _custom_blocks(self, evr):\n-        return None\n-\n     def _get_report_element(self, docs_link):\n-        if docs_link is None:\n-            logger.warn(\"No docs link found. Skipping data docs link in slack message.\")\n-            return\n-\n-        if \"file://\" in docs_link:\n-            # handle special case since Slack does not render these links\n-            report_element = {\n-                \"type\": \"section\",\n-                \"text\": {\n-                    \"type\": \"mrkdwn\",\n-                    \"text\": f\"*DataDocs* can be found here: `{docs_link}` \\n (Please copy and paste link into a browser to view)\\n\",\n-                },\n-            }\n+        report_element = None\n+        if docs_link:\n+            try:\n+                if \"file://\" in docs_link:\n+                    # handle special case since Slack does not render these links\n+                    report_element = {\n+                        \"type\": \"section\",\n+                        \"text\": {\n+                            \"type\": \"mrkdwn\",\n+                            \"text\": f\"*DataDocs* can be found here: `{docs_link}` \\n (Please copy and paste link into a browser to view)\\n\",\n+                        },\n+                    }\n+                else:\n+                    report_element = {\n+                        \"type\": \"section\",\n+                        \"text\": {\n+                            \"type\": \"mrkdwn\",\n+                            \"text\": f\"*DataDocs* can be found here: <{docs_link}|{docs_link}>\",\n+                        },\n+                    }\n+            except Exception as e:\n+                logger.warning(\n+                    f\"\"\"SlackRenderer had a problem with generating the docs link.\n+                    link used to generate the docs link is: {docs_link} and is of type: {type(docs_link)}.\n+                    Error: {e}\"\"\"\n+                )\n+                return\n         else:\n-            report_element = {\n-                \"type\": \"section\",\n-                \"text\": {\n-                    \"type\": \"mrkdwn\",\n-                    \"text\": f\"*DataDocs* can be found here: <{docs_link}|{docs_link}>\",\n-                },\n-            }\n+            logger.warning(\n+                \"No docs link found. Skipping data docs link in Slack message.\"\n+            )\n         return report_element\n", "issue": "Error in slack_notification Action\nHi Guys,\r\nI have 3 pipelines with great expectations, but one pipeline started to give some errors:\r\n\r\n`Error running action with name notify_slack\r\nTraceback (most recent call last):\r\n  File \"/usr/local/lib/python3.7/site-packages/great_expectations/validation_operators/validation_operators.py\", line 384, in _run_actions\r\n    payload=batch_actions_results,\r\n  File \"/usr/local/lib/python3.7/site-packages/great_expectations/validation_operators/actions.py\", line 55, in run\r\n    **kwargs,\r\n  File \"/usr/local/lib/python3.7/site-packages/great_expectations/validation_operators/actions.py\", line 170, in _run\r\n    validation_result_suite, data_docs_pages, self.notify_with\r\n  File \"/usr/local/lib/python3.7/site-packages/great_expectations/render/renderer/slack_renderer.py\", line 101, in render\r\n    report_element = self._get_report_element(docs_link)\r\n  File \"/usr/local/lib/python3.7/site-packages/great_expectations/render/renderer/slack_renderer.py\", line 155, in _get_report_element\r\n    if \"file:///\" in docs_link:\r\nTypeError: argument of type 'NoneType' is not iterable\r\nTraceback (most recent call last):\r\n  File \"fact_demand_coverage_datalake_datasets_job.py\", line 90, in <module>\r\n    expectation_suite=expectation_suite_name_for_validations\r\n  File \"/mnt1/yarn/usercache/hadoop/appcache/application_1603978914184_5458/container_1603978914184_5458_01_000001/data_quality.zip/data_quality/ge_validation.py\", line 174, in validate\r\n  File \"/usr/local/lib/python3.7/site-packages/great_expectations/core/usage_statistics/usage_statistics.py\", line 257, in usage_statistics_wrapped_method\r\n    result = func(*args, **kwargs)\r\n  File \"/usr/local/lib/python3.7/site-packages/great_expectations/data_context/data_context.py\", line 1022, in run_validation_operator\r\n    **kwargs,\r\n  File \"/usr/local/lib/python3.7/site-packages/great_expectations/validation_operators/validation_operators.py\", line 334, in run\r\n    run_id,\r\n  File \"/usr/local/lib/python3.7/site-packages/great_expectations/validation_operators/validation_operators.py\", line 399, in _run_actions\r\n    raise e\r\n  File \"/usr/local/lib/python3.7/site-packages/great_expectations/validation_operators/validation_operators.py\", line 384, in _run_actions\r\n    payload=batch_actions_results,\r\n  File \"/usr/local/lib/python3.7/site-packages/great_expectations/validation_operators/actions.py\", line 55, in run\r\n    **kwargs,\r\n  File \"/usr/local/lib/python3.7/site-packages/great_expectations/validation_operators/actions.py\", line 170, in _run\r\n    validation_result_suite, data_docs_pages, self.notify_with\r\n  File \"/usr/local/lib/python3.7/site-packages/great_expectations/render/renderer/slack_renderer.py\", line 101, in render\r\n    report_element = self._get_report_element(docs_link)\r\n  File \"/usr/local/lib/python3.7/site-packages/great_expectations/render/renderer/slack_renderer.py\", line 155, in _get_report_element\r\n    if \"file:///\" in docs_link:\r\nTypeError: argument of type 'NoneType' is not iterable`\r\n\r\nThe stranger thing with this error, the error doesn't happen every day, for example yesterday it worked fine.\n", "before_files": [{"content": "import logging\n\nfrom great_expectations.exceptions import InvalidKeyError\n\nlogger = logging.getLogger(__name__)\n\nfrom ...core.id_dict import BatchKwargs\nfrom .renderer import Renderer\n\n\nclass SlackRenderer(Renderer):\n    def __init__(self):\n        super().__init__()\n\n    def render(\n        self, validation_result=None, data_docs_pages=None, notify_with=None,\n    ):\n        default_text = (\n            \"No validation occurred. Please ensure you passed a validation_result.\"\n        )\n        status = \"Failed :x:\"\n\n        title_block = {\n            \"type\": \"section\",\n            \"text\": {\"type\": \"mrkdwn\", \"text\": default_text,},\n        }\n\n        query = {\n            \"blocks\": [title_block],\n            # this abbreviated root level \"text\" will show up in the notification and not the message\n            \"text\": default_text,\n        }\n\n        if validation_result:\n            expectation_suite_name = validation_result.meta.get(\n                \"expectation_suite_name\", \"__no_expectation_suite_name__\"\n            )\n\n            if \"batch_kwargs\" in validation_result.meta:\n                data_asset_name = validation_result.meta[\"batch_kwargs\"].get(\n                    \"data_asset_name\", \"__no_data_asset_name__\"\n                )\n            else:\n                data_asset_name = \"__no_data_asset_name__\"\n\n            n_checks_succeeded = validation_result.statistics[\"successful_expectations\"]\n            n_checks = validation_result.statistics[\"evaluated_expectations\"]\n            run_id = validation_result.meta.get(\"run_id\", \"__no_run_id__\")\n            batch_id = BatchKwargs(\n                validation_result.meta.get(\"batch_kwargs\", {})\n            ).to_id()\n            check_details_text = (\n                f\"*{n_checks_succeeded}* of *{n_checks}* expectations were met\"\n            )\n\n            if validation_result.success:\n                status = \"Success :tada:\"\n\n            summary_text = f\"\"\"*Batch Validation Status*: {status}\n*Expectation suite name*: `{expectation_suite_name}`\n*Data asset name*: `{data_asset_name}`\n*Run ID*: `{run_id}`\n*Batch ID*: `{batch_id}`\n*Summary*: {check_details_text}\"\"\"\n            query[\"blocks\"][0][\"text\"][\"text\"] = summary_text\n            # this abbreviated root level \"text\" will show up in the notification and not the message\n            query[\"text\"] = f\"{expectation_suite_name}: {status}\"\n\n            if data_docs_pages:\n                if notify_with is not None:\n                    for docs_link_key in notify_with:\n                        if docs_link_key in data_docs_pages.keys():\n                            docs_link = data_docs_pages[docs_link_key]\n                            report_element = self._get_report_element(docs_link)\n                        else:\n                            logger.critical(\n                                f\"*ERROR*: Slack is trying to provide a link to the following DataDocs: `{str(docs_link_key)}`, but it is not configured under `data_docs_sites` in the `great_expectations.yml`\\n\"\n                            )\n                            report_element = {\n                                \"type\": \"section\",\n                                \"text\": {\n                                    \"type\": \"mrkdwn\",\n                                    \"text\": f\"*ERROR*: Slack is trying to provide a link to the following DataDocs: `{str(docs_link_key)}`, but it is not configured under `data_docs_sites` in the `great_expectations.yml`\\n\",\n                                },\n                            }\n                        if report_element:\n                            query[\"blocks\"].append(report_element)\n                else:\n                    for docs_link_key in data_docs_pages.keys():\n                        if docs_link_key == \"class\":\n                            continue\n                        docs_link = data_docs_pages[docs_link_key]\n                        report_element = self._get_report_element(docs_link)\n                        if report_element:\n                            query[\"blocks\"].append(report_element)\n\n            if \"result_reference\" in validation_result.meta:\n                result_reference = validation_result.meta[\"result_reference\"]\n                report_element = {\n                    \"type\": \"section\",\n                    \"text\": {\n                        \"type\": \"mrkdwn\",\n                        \"text\": f\"- *Validation Report*: {result_reference}\",\n                    },\n                }\n                query[\"blocks\"].append(report_element)\n\n            if \"dataset_reference\" in validation_result.meta:\n                dataset_reference = validation_result.meta[\"dataset_reference\"]\n                dataset_element = {\n                    \"type\": \"section\",\n                    \"text\": {\n                        \"type\": \"mrkdwn\",\n                        \"text\": f\"- *Validation data asset*: {dataset_reference}\",\n                    },\n                }\n                query[\"blocks\"].append(dataset_element)\n\n        custom_blocks = self._custom_blocks(evr=validation_result)\n        if custom_blocks:\n            query[\"blocks\"].append(custom_blocks)\n\n        documentation_url = \"https://docs.greatexpectations.io/en/latest/guides/tutorials/getting_started/set_up_data_docs.html\"\n        footer_section = {\n            \"type\": \"context\",\n            \"elements\": [\n                {\n                    \"type\": \"mrkdwn\",\n                    \"text\": f\"Learn how to review validation results in Data Docs: {documentation_url}\",\n                }\n            ],\n        }\n\n        divider_block = {\"type\": \"divider\"}\n        query[\"blocks\"].append(divider_block)\n        query[\"blocks\"].append(footer_section)\n        return query\n\n    def _custom_blocks(self, evr):\n        return None\n\n    def _get_report_element(self, docs_link):\n        if docs_link is None:\n            logger.warn(\"No docs link found. Skipping data docs link in slack message.\")\n            return\n\n        if \"file://\" in docs_link:\n            # handle special case since Slack does not render these links\n            report_element = {\n                \"type\": \"section\",\n                \"text\": {\n                    \"type\": \"mrkdwn\",\n                    \"text\": f\"*DataDocs* can be found here: `{docs_link}` \\n (Please copy and paste link into a browser to view)\\n\",\n                },\n            }\n        else:\n            report_element = {\n                \"type\": \"section\",\n                \"text\": {\n                    \"type\": \"mrkdwn\",\n                    \"text\": f\"*DataDocs* can be found here: <{docs_link}|{docs_link}>\",\n                },\n            }\n        return report_element\n", "path": "great_expectations/render/renderer/slack_renderer.py"}], "after_files": [{"content": "import logging\n\nfrom great_expectations.exceptions import InvalidKeyError\n\nlogger = logging.getLogger(__name__)\n\nfrom ...core.id_dict import BatchKwargs\nfrom .renderer import Renderer\n\n\nclass SlackRenderer(Renderer):\n    def __init__(self):\n        super().__init__()\n\n    def render(\n        self, validation_result=None, data_docs_pages=None, notify_with=None,\n    ):\n        default_text = (\n            \"No validation occurred. Please ensure you passed a validation_result.\"\n        )\n        status = \"Failed :x:\"\n\n        title_block = {\n            \"type\": \"section\",\n            \"text\": {\"type\": \"mrkdwn\", \"text\": default_text,},\n        }\n\n        query = {\n            \"blocks\": [title_block],\n            # this abbreviated root level \"text\" will show up in the notification and not the message\n            \"text\": default_text,\n        }\n\n        if validation_result:\n            expectation_suite_name = validation_result.meta.get(\n                \"expectation_suite_name\", \"__no_expectation_suite_name__\"\n            )\n\n            if \"batch_kwargs\" in validation_result.meta:\n                data_asset_name = validation_result.meta[\"batch_kwargs\"].get(\n                    \"data_asset_name\", \"__no_data_asset_name__\"\n                )\n            else:\n                data_asset_name = \"__no_data_asset_name__\"\n\n            n_checks_succeeded = validation_result.statistics[\"successful_expectations\"]\n            n_checks = validation_result.statistics[\"evaluated_expectations\"]\n            run_id = validation_result.meta.get(\"run_id\", \"__no_run_id__\")\n            batch_id = BatchKwargs(\n                validation_result.meta.get(\"batch_kwargs\", {})\n            ).to_id()\n            check_details_text = (\n                f\"*{n_checks_succeeded}* of *{n_checks}* expectations were met\"\n            )\n\n            if validation_result.success:\n                status = \"Success :tada:\"\n\n            summary_text = f\"\"\"*Batch Validation Status*: {status}\n*Expectation suite name*: `{expectation_suite_name}`\n*Data asset name*: `{data_asset_name}`\n*Run ID*: `{run_id}`\n*Batch ID*: `{batch_id}`\n*Summary*: {check_details_text}\"\"\"\n            query[\"blocks\"][0][\"text\"][\"text\"] = summary_text\n            # this abbreviated root level \"text\" will show up in the notification and not the message\n            query[\"text\"] = f\"{expectation_suite_name}: {status}\"\n\n            if data_docs_pages:\n                if notify_with is not None:\n                    for docs_link_key in notify_with:\n                        if docs_link_key in data_docs_pages.keys():\n                            docs_link = data_docs_pages[docs_link_key]\n                            report_element = self._get_report_element(docs_link)\n                        else:\n                            logger.critical(\n                                f\"*ERROR*: Slack is trying to provide a link to the following DataDocs: `{str(docs_link_key)}`, but it is not configured under `data_docs_sites` in the `great_expectations.yml`\\n\"\n                            )\n                            report_element = {\n                                \"type\": \"section\",\n                                \"text\": {\n                                    \"type\": \"mrkdwn\",\n                                    \"text\": f\"*ERROR*: Slack is trying to provide a link to the following DataDocs: `{str(docs_link_key)}`, but it is not configured under `data_docs_sites` in the `great_expectations.yml`\\n\",\n                                },\n                            }\n                        if report_element:\n                            query[\"blocks\"].append(report_element)\n                else:\n                    for docs_link_key in data_docs_pages.keys():\n                        if docs_link_key == \"class\":\n                            continue\n                        docs_link = data_docs_pages[docs_link_key]\n                        report_element = self._get_report_element(docs_link)\n                        if report_element:\n                            query[\"blocks\"].append(report_element)\n\n            if \"result_reference\" in validation_result.meta:\n                result_reference = validation_result.meta[\"result_reference\"]\n                report_element = {\n                    \"type\": \"section\",\n                    \"text\": {\n                        \"type\": \"mrkdwn\",\n                        \"text\": f\"- *Validation Report*: {result_reference}\",\n                    },\n                }\n                query[\"blocks\"].append(report_element)\n\n            if \"dataset_reference\" in validation_result.meta:\n                dataset_reference = validation_result.meta[\"dataset_reference\"]\n                dataset_element = {\n                    \"type\": \"section\",\n                    \"text\": {\n                        \"type\": \"mrkdwn\",\n                        \"text\": f\"- *Validation data asset*: {dataset_reference}\",\n                    },\n                }\n                query[\"blocks\"].append(dataset_element)\n\n        documentation_url = \"https://docs.greatexpectations.io/en/latest/guides/tutorials/getting_started/set_up_data_docs.html\"\n        footer_section = {\n            \"type\": \"context\",\n            \"elements\": [\n                {\n                    \"type\": \"mrkdwn\",\n                    \"text\": f\"Learn how to review validation results in Data Docs: {documentation_url}\",\n                }\n            ],\n        }\n\n        divider_block = {\"type\": \"divider\"}\n        query[\"blocks\"].append(divider_block)\n        query[\"blocks\"].append(footer_section)\n        return query\n\n    def _get_report_element(self, docs_link):\n        report_element = None\n        if docs_link:\n            try:\n                if \"file://\" in docs_link:\n                    # handle special case since Slack does not render these links\n                    report_element = {\n                        \"type\": \"section\",\n                        \"text\": {\n                            \"type\": \"mrkdwn\",\n                            \"text\": f\"*DataDocs* can be found here: `{docs_link}` \\n (Please copy and paste link into a browser to view)\\n\",\n                        },\n                    }\n                else:\n                    report_element = {\n                        \"type\": \"section\",\n                        \"text\": {\n                            \"type\": \"mrkdwn\",\n                            \"text\": f\"*DataDocs* can be found here: <{docs_link}|{docs_link}>\",\n                        },\n                    }\n            except Exception as e:\n                logger.warning(\n                    f\"\"\"SlackRenderer had a problem with generating the docs link.\n                    link used to generate the docs link is: {docs_link} and is of type: {type(docs_link)}.\n                    Error: {e}\"\"\"\n                )\n                return\n        else:\n            logger.warning(\n                \"No docs link found. Skipping data docs link in Slack message.\"\n            )\n        return report_element\n", "path": "great_expectations/render/renderer/slack_renderer.py"}]}