Skip to content

Commit 828b046

Browse files
committed
feat(ux): improve connection error reporting
1 parent 1f9b3fc commit 828b046

File tree

2 files changed

+28
-3
lines changed

2 files changed

+28
-3
lines changed

src/poetry/utils/authenticator.py

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222

2323
from poetry.__version__ import __version__
2424
from poetry.config.config import Config
25+
from poetry.console.exceptions import ConsoleMessage
26+
from poetry.console.exceptions import PoetryRuntimeError
2527
from poetry.exceptions import PoetryError
2628
from poetry.utils.constants import REQUESTS_TIMEOUT
2729
from poetry.utils.constants import RETRY_AFTER_HEADER
@@ -230,7 +232,28 @@ def request(
230232
resp = session.send(prepared_request, **send_kwargs)
231233
except (requests.exceptions.ConnectionError, OSError) as e:
232234
if is_last_attempt:
233-
raise e
235+
parsed_url = urllib.parse.urlsplit(url)
236+
exc = PoetryRuntimeError.create(
237+
reason=f"<error>All attempts to connect to <c1>{parsed_url.netloc}</> failed.</>",
238+
exception=e,
239+
)
240+
exc.append(
241+
ConsoleMessage(
242+
"the server is not responding to requests at the moment\n"
243+
"the hostname cannot be resolved by your DNS\n"
244+
"your network is not connected to the internet\n"
245+
)
246+
.indent(" - ")
247+
.make_section("Probable Causes")
248+
.wrap("warning")
249+
)
250+
exc.append(
251+
ConsoleMessage(
252+
f"<b>Note:</> The path requested was <c1>{parsed_url.path}</>.",
253+
debug=True,
254+
)
255+
)
256+
raise exc
234257
else:
235258
if resp.status_code not in STATUS_FORCELIST or is_last_attempt:
236259
if raise_for_status:
@@ -245,7 +268,7 @@ def request(
245268
continue
246269

247270
# this should never really be hit under any sane circumstance
248-
raise PoetryError("Failed HTTP {} request", method.upper())
271+
raise PoetryError(f"Failed HTTP request: {method.upper()} {url}")
249272

250273
def _get_backoff(self, response: requests.Response | None, attempt: int) -> float:
251274
if response is not None:

tests/utils/test_authenticator.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from cleo.io.null_io import NullIO
1717
from keyring.credentials import SimpleCredential
1818

19+
from poetry.console.exceptions import PoetryRuntimeError
1920
from poetry.utils.authenticator import Authenticator
2021
from poetry.utils.authenticator import RepositoryCertificateConfig
2122
from poetry.utils.password_manager import PoetryKeyring
@@ -279,9 +280,10 @@ def callback(*_: Any, **___: Any) -> None:
279280
http.register_uri(httpretty.GET, sdist_uri, body=callback)
280281
authenticator = Authenticator(config, NullIO())
281282

282-
with pytest.raises(requests.exceptions.ConnectionError):
283+
with pytest.raises(PoetryRuntimeError) as e:
283284
authenticator.request("get", sdist_uri)
284285

286+
assert str(e.value) == "All attempts to connect to foo.bar failed."
285287
assert sleep.call_count == 5
286288

287289

0 commit comments

Comments
 (0)