diff --git a/rsconnect/api.py b/rsconnect/api.py index 3fd71479..6b09ce14 100644 --- a/rsconnect/api.py +++ b/rsconnect/api.py @@ -28,7 +28,7 @@ from .metadata import ServerStore, AppStore from .exception import RSConnectException from .bundle import _default_title, fake_module_file_from_directory -from .timeouts import get_task_timeout +from .timeouts import get_task_timeout, get_task_timeout_help_message class AbstractRemoteServer: @@ -313,7 +313,7 @@ def wait_for_task( time_slept = 0 while True: if (time.time() - start_time) > timeout: - raise RSConnectException("Task timed out after %d seconds" % timeout) + raise RSConnectException(get_task_timeout_help_message(timeout)) elif abort_func(): raise RSConnectException("Task aborted.") @@ -1195,7 +1195,7 @@ def wait_until_task_is_successful(self, task_id, timeout=get_task_timeout()): time.sleep(2) if not finished: - raise RSConnectException("Application deployment timed out.") + raise RSConnectException(get_task_timeout_help_message(timeout)) if status != "success": raise RSConnectException("Application deployment failed with error: {}".format(error)) diff --git a/rsconnect/timeouts.py b/rsconnect/timeouts.py index 77ff1146..82a60374 100644 --- a/rsconnect/timeouts.py +++ b/rsconnect/timeouts.py @@ -1,4 +1,6 @@ import os +import textwrap + from typing import Union from rsconnect.exception import RSConnectException @@ -70,3 +72,18 @@ def get_task_timeout() -> int: raise RSConnectException(f"'CONNECT_TASK_TIMEOUT' is set to '{timeout}'. The value must be a positive integer.") return timeout + + +def get_task_timeout_help_message(timeout=get_task_timeout()) -> str: + """Gets a human friendly help message for adjusting the task timeout value.""" + + return f"The task timed out after {timeout} seconds." + textwrap.dedent( + f""" + + You may try increasing the task timeout value using the {_CONNECT_TASK_TIMEOUT_KEY} environment variable. The default value is {_CONNECT_TASK_TIMEOUT_DEFAULT_VALUE} seconds. The current value is {get_task_timeout()} seconds. + + Example: + + CONNECT_TASK_TIMEOUT={_CONNECT_TASK_TIMEOUT_DEFAULT_VALUE} rsconnect deploy api --server --api-key ./ + """ # noqa: E501 + ) diff --git a/tests/test_timeouts.py b/tests/test_timeouts.py index 2698da09..89b637ed 100644 --- a/tests/test_timeouts.py +++ b/tests/test_timeouts.py @@ -4,7 +4,7 @@ from unittest.mock import patch from rsconnect.exception import RSConnectException -from rsconnect.timeouts import get_request_timeout, get_task_timeout +from rsconnect.timeouts import get_request_timeout, get_task_timeout, get_task_timeout_help_message class GetRequestTimeoutTestCase(TestCase): @@ -56,3 +56,11 @@ def test_get_negative_timeout_from_environment(self): with patch.dict(os.environ, {"CONNECT_TASK_TIMEOUT": "-24"}): with self.assertRaises(RSConnectException): get_task_timeout() + +class GetTaskTimeoutHelpMessageTestCase(TestCase): + def test_get_task_timeout_help_message(self): + res = get_task_timeout_help_message(1) + self.assertTrue("The task timed out after 1 seconds." in res) + self.assertTrue("You may try increasing the task timeout value using the CONNECT_TASK_TIMEOUT environment variable." in res) # noqa: E501 + self.assertTrue("The default value is 86400 seconds." in res) + self.assertTrue("The current value is 86400 seconds." in res)