diff --git a/uaclient/actions.py b/uaclient/actions.py index 2f0efbf34f..18f363a7d8 100644 --- a/uaclient/actions.py +++ b/uaclient/actions.py @@ -64,7 +64,10 @@ def attach_with_token( ) except exceptions.UrlError as e: LOG.exception(str(e)) - raise exceptions.ConnectivityError() + raise exceptions.ConnectivityError( + url=e.url, + cause=e.cause_error, + ) cfg.machine_token_file.write(new_machine_token) diff --git a/uaclient/api/tests/test_api_u_pro_attach_magic_wait_v1.py b/uaclient/api/tests/test_api_u_pro_attach_magic_wait_v1.py index aa65d04c45..c6f22f4cdf 100644 --- a/uaclient/api/tests/test_api_u_pro_attach_magic_wait_v1.py +++ b/uaclient/api/tests/test_api_u_pro_attach_magic_wait_v1.py @@ -67,10 +67,10 @@ def test_wait_fails_after_number_of_connectiviry_errors( ): magic_token = "test-id" m_attach_token_info.side_effect = [ - exceptions.ConnectivityError(), - exceptions.ConnectivityError(), - exceptions.ConnectivityError(), - exceptions.ConnectivityError(), + exceptions.ConnectivityError(url="url", cause="cause"), + exceptions.ConnectivityError(url="url", cause="cause"), + exceptions.ConnectivityError(url="url", cause="cause"), + exceptions.ConnectivityError(url="url", cause="cause"), ] options = MagicAttachWaitOptions(magic_token=magic_token) @@ -86,9 +86,9 @@ def test_wait_succeeds_after_number_of_connectivity_errors( ): magic_token = "test-id" m_attach_token_info.side_effect = [ - exceptions.ConnectivityError(), - exceptions.ConnectivityError(), - exceptions.ConnectivityError(), + exceptions.ConnectivityError(url="url", cause="cause"), + exceptions.ConnectivityError(url="url", cause="cause"), + exceptions.ConnectivityError(url="url", cause="cause"), { "token": magic_token, "expires": "2100-06-09T18:14:55.323733Z", @@ -113,7 +113,7 @@ def test_wait_succeeds_after_unavailable_server( ): magic_token = "test-id" m_attach_token_info.side_effect = [ - exceptions.ConnectivityError(), + exceptions.ConnectivityError(url="url", cause="cause"), exceptions.MagicAttachUnavailable(), exceptions.MagicAttachUnavailable(), { diff --git a/uaclient/cli/__init__.py b/uaclient/cli/__init__.py index a8c38a52d9..e277b98259 100644 --- a/uaclient/cli/__init__.py +++ b/uaclient/cli/__init__.py @@ -1720,7 +1720,10 @@ def wrapper(*args, **kwargs): "Failed to access URL: %s", exc.url, exc_info=exc ) - msg = messages.E_CONNECTIVITY_ERROR + msg = messages.E_CONNECTIVITY_ERROR.format( + url=exc.url, + cause=exc.cause_error, + ) event.error(error_msg=msg.msg, error_code=msg.name) event.info(info_msg=msg.msg, file_type=sys.stderr) diff --git a/uaclient/cli/tests/test_cli.py b/uaclient/cli/tests/test_cli.py index 461d72edf4..9e4c1df8a5 100644 --- a/uaclient/cli/tests/test_cli.py +++ b/uaclient/cli/tests/test_cli.py @@ -657,7 +657,11 @@ def test_url_error_handled_gracefully( assert [ mock.call( - info_msg=messages.E_CONNECTIVITY_ERROR.msg, file_type=mock.ANY + info_msg=messages.E_CONNECTIVITY_ERROR.format( + url=error_url, + cause="[Errno -2] Name or service not known", + ).msg, + file_type=mock.ANY, ) ] == m_event_info.call_args_list assert [expected_log_call] == m_log_exception.call_args_list diff --git a/uaclient/contract.py b/uaclient/contract.py index 0418956d97..ad91af395c 100644 --- a/uaclient/contract.py +++ b/uaclient/contract.py @@ -266,7 +266,7 @@ def get_magic_attach_token_info(self, magic_token: str) -> Dict[str, Any]: ) except exceptions.UrlError as e: LOG.exception(e) - raise exceptions.ConnectivityError() + raise exceptions.ConnectivityError(url=e.url, cause=e.cause_error) if response.code == 401: raise exceptions.MagicAttachTokenError() if response.code == 503: @@ -292,7 +292,10 @@ def new_magic_attach_token(self) -> Dict[str, Any]: ) except exceptions.UrlError as e: LOG.exception(e) - raise exceptions.ConnectivityError() + raise exceptions.ConnectivityError( + url=e.url, + cause=e.cause_error, + ) if response.code == 503: raise exceptions.MagicAttachUnavailable() if response.code != 200: @@ -317,7 +320,10 @@ def revoke_magic_attach_token(self, magic_token: str): ) except exceptions.UrlError as e: LOG.exception(e) - raise exceptions.ConnectivityError() + raise exceptions.ConnectivityError( + url=e.url, + cause=e.cause_error, + ) if response.code == 400: raise exceptions.MagicAttachTokenAlreadyActivated() if response.code == 401: diff --git a/uaclient/daemon/tests/test_retry_auto_attach.py b/uaclient/daemon/tests/test_retry_auto_attach.py index 5be81d687e..30680eadd1 100644 --- a/uaclient/daemon/tests/test_retry_auto_attach.py +++ b/uaclient/daemon/tests/test_retry_auto_attach.py @@ -43,7 +43,7 @@ class TestFullAutoAttachToFailureReason: 'an error from Canonical servers: "response"', ), ( - exceptions.ConnectivityError(), + exceptions.ConnectivityError(url="test", cause="test"), "a connectivity error", ), ( diff --git a/uaclient/exceptions.py b/uaclient/exceptions.py index 38d7c899b5..034d5038ec 100644 --- a/uaclient/exceptions.py +++ b/uaclient/exceptions.py @@ -31,6 +31,7 @@ def __init__( cause_error = str(cause) super().__init__(cause_error) self.url = url + self.cause_error = cause_error class ProcessExecutionError(IOError): @@ -207,7 +208,7 @@ class ProxyAuthenticationFailed(UbuntuProError): class ConnectivityError(UbuntuProError): - _msg = messages.E_CONNECTIVITY_ERROR + _formatted_msg = messages.E_CONNECTIVITY_ERROR class ExternalAPIError(UbuntuProError): diff --git a/uaclient/messages/__init__.py b/uaclient/messages/__init__.py index 9c7a41fd93..d4d753c095 100644 --- a/uaclient/messages/__init__.py +++ b/uaclient/messages/__init__.py @@ -2019,12 +2019,13 @@ def __repr__(self): "proxy-auth-fail", t.gettext("Proxy authentication failed") ) -E_CONNECTIVITY_ERROR = NamedMessage( +E_CONNECTIVITY_ERROR = FormattedNamedMessage( "connectivity-error", t.gettext( """\ -Failed to connect to authentication server -Check your Internet connection and try again.""" +Failed to connect to {url} +{cause} +""" ), ) diff --git a/uaclient/tests/test_contract.py b/uaclient/tests/test_contract.py index 8f7c6141e7..3ebcb6c7f4 100644 --- a/uaclient/tests/test_contract.py +++ b/uaclient/tests/test_contract.py @@ -530,7 +530,10 @@ def test_new_magic_attach_token_successfull( ( exceptions.UrlError("cause", "url"), exceptions.ConnectivityError, - messages.E_CONNECTIVITY_ERROR, + messages.E_CONNECTIVITY_ERROR.format( + url="url", + cause="cause", + ), ), ( [ @@ -609,7 +612,13 @@ def test_request_magic_attach_id_info_fails( with pytest.raises(exceptions.ConnectivityError) as exc_error: client.get_magic_attach_token_info(magic_token=magic_token) - assert messages.E_CONNECTIVITY_ERROR.msg == exc_error.value.msg + assert ( + messages.E_CONNECTIVITY_ERROR.format( + url="url", + cause="cause", + ).msg + == exc_error.value.msg + ) assert messages.E_CONNECTIVITY_ERROR.name == exc_error.value.msg_code @pytest.mark.parametrize( @@ -656,7 +665,13 @@ def test_revoke_magic_attach_token_fails( with pytest.raises(exceptions.ConnectivityError) as exc_error: client.revoke_magic_attach_token(magic_token=magic_token) - assert messages.E_CONNECTIVITY_ERROR.msg == exc_error.value.msg + assert ( + messages.E_CONNECTIVITY_ERROR.format( + url="url", + cause="cause", + ).msg + == exc_error.value.msg + ) assert messages.E_CONNECTIVITY_ERROR.name == exc_error.value.msg_code @pytest.mark.parametrize(