From 81c2cdc5f357f15558e6809c2a6c4edbc9eddbb4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 31 Jul 2026 23:56:25 +0000 Subject: [PATCH 1/3] Initial plan From 3a433def5ef1dd2e5b98505c6a29077d0c5c67b0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 1 Aug 2026 00:05:20 +0000 Subject: [PATCH 2/3] [appservice] Surface Kudu 409 response body in webapp webjob triggered list --- .../cli/command_modules/appservice/custom.py | 16 +++++- .../latest/test_webapp_commands_thru_mock.py | 49 ++++++++++++++++++- 2 files changed, 62 insertions(+), 3 deletions(-) diff --git a/src/azure-cli/azure/cli/command_modules/appservice/custom.py b/src/azure-cli/azure/cli/command_modules/appservice/custom.py index 0f247b322e2..ec892690d68 100644 --- a/src/azure-cli/azure/cli/command_modules/appservice/custom.py +++ b/src/azure-cli/azure/cli/command_modules/appservice/custom.py @@ -10450,7 +10450,21 @@ def remove_continuous_webjob(cmd, resource_group_name, name, webjob_name, slot=N def list_triggered_webjobs(cmd, resource_group_name, name, slot=None): - return _generic_site_operation(cmd.cli_ctx, resource_group_name, name, 'list_triggered_web_jobs', slot) + import json + try: + return _generic_site_operation(cmd.cli_ctx, resource_group_name, name, 'list_triggered_web_jobs', slot) + except HttpResponseError as ex: + if ex.status_code == 409: + try: + response_text = ex.response.text() + except TypeError: + response_text = ex.response.text + try: + message = json.loads(response_text).get('error') or str(ex) + except (ValueError, AttributeError): + message = str(ex) + raise UnclassifiedUserFault(message) + raise def run_triggered_webjob(cmd, resource_group_name, name, webjob_name, slot=None): diff --git a/src/azure-cli/azure/cli/command_modules/appservice/tests/latest/test_webapp_commands_thru_mock.py b/src/azure-cli/azure/cli/command_modules/appservice/tests/latest/test_webapp_commands_thru_mock.py index 697496f307c..e44fe78ad3a 100644 --- a/src/azure-cli/azure/cli/command_modules/appservice/tests/latest/test_webapp_commands_thru_mock.py +++ b/src/azure-cli/azure/cli/command_modules/appservice/tests/latest/test_webapp_commands_thru_mock.py @@ -16,7 +16,8 @@ MutuallyExclusiveArgumentError, ArgumentUsageError, AzureResponseError, - ResourceNotFoundError) + ResourceNotFoundError, + UnclassifiedUserFault) from azure.cli.command_modules.appservice.custom import (set_deployment_user, update_git_token, add_hostname, update_site_configs, @@ -41,7 +42,8 @@ list_startup_logs, show_startup_log, troubleshoot_status, - create_webapp) + create_webapp, + list_triggered_webjobs) # pylint: disable=line-too-long from azure.cli.core.profiles import ResourceType @@ -2165,5 +2167,48 @@ def test_get_java_runtimes_from_container_settings_reads_mapping(self): self.assertTrue(all(is_auto for _, _, is_auto in runtimes)) +class TestListTriggeredWebjobs(unittest.TestCase): + def _build_http_response_error(self, status_code, body_text): + """Build an HttpResponseError with the given status code and response body text.""" + response_mock = mock.MagicMock() + response_mock.text.return_value = body_text + error = HttpResponseError(message="Operation returned an invalid status '{}'".format(status_code)) + error.status_code = status_code + error.response = response_mock + return error + + @mock.patch('azure.cli.command_modules.appservice.custom._generic_site_operation') + def test_list_triggered_webjobs_409_surfaces_kudu_error(self, generic_op_mock): + """list_triggered_webjobs raises UnclassifiedUserFault with the Kudu body on HTTP 409.""" + kudu_message = ("The web app is not configured to run the web job. " + "Please enable running web jobs before calling the API.") + body = '{{"error": "{}"}}'.format(kudu_message) + generic_op_mock.side_effect = self._build_http_response_error(409, body) + + cmd = _get_test_cmd() + with self.assertRaises(UnclassifiedUserFault) as ctx: + list_triggered_webjobs(cmd, 'rg', 'myapp') + + self.assertIn('web job', str(ctx.exception)) + + @mock.patch('azure.cli.command_modules.appservice.custom._generic_site_operation') + def test_list_triggered_webjobs_non_409_reraises(self, generic_op_mock): + """list_triggered_webjobs re-raises HttpResponseError when status is not 409.""" + generic_op_mock.side_effect = self._build_http_response_error(500, '{"error": "Internal Server Error"}') + + cmd = _get_test_cmd() + with self.assertRaises(HttpResponseError): + list_triggered_webjobs(cmd, 'rg', 'myapp') + + @mock.patch('azure.cli.command_modules.appservice.custom._generic_site_operation') + def test_list_triggered_webjobs_409_fallback_when_body_unparseable(self, generic_op_mock): + """list_triggered_webjobs raises UnclassifiedUserFault even when body is not valid JSON.""" + generic_op_mock.side_effect = self._build_http_response_error(409, 'not json at all') + + cmd = _get_test_cmd() + with self.assertRaises(UnclassifiedUserFault): + list_triggered_webjobs(cmd, 'rg', 'myapp') + + if __name__ == '__main__': unittest.main() \ No newline at end of file From 490698937ee4d2a518e852f6a7016ac32f43fc39 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 1 Aug 2026 02:29:18 +0000 Subject: [PATCH 3/3] fix: remove redundant local `import json` in list_triggered_webjobs --- src/azure-cli/azure/cli/command_modules/appservice/custom.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/azure-cli/azure/cli/command_modules/appservice/custom.py b/src/azure-cli/azure/cli/command_modules/appservice/custom.py index ec892690d68..c43e89cf3cb 100644 --- a/src/azure-cli/azure/cli/command_modules/appservice/custom.py +++ b/src/azure-cli/azure/cli/command_modules/appservice/custom.py @@ -10450,7 +10450,6 @@ def remove_continuous_webjob(cmd, resource_group_name, name, webjob_name, slot=N def list_triggered_webjobs(cmd, resource_group_name, name, slot=None): - import json try: return _generic_site_operation(cmd.cli_ctx, resource_group_name, name, 'list_triggered_web_jobs', slot) except HttpResponseError as ex: