Skip to content

Commit 93b9d14

Browse files
committed
Better incomplete download error message
1 parent d655669 commit 93b9d14

File tree

2 files changed

+38
-15
lines changed

2 files changed

+38
-15
lines changed

src/pip/_internal/exceptions.py

+34
Original file line numberDiff line numberDiff line change
@@ -656,3 +656,37 @@ def __str__(self) -> str:
656656
assert self.error is not None
657657
message_part = f".\n{self.error}\n"
658658
return f"Configuration file {self.reason}{message_part}"
659+
660+
661+
class IncompleteDownloadError(DiagnosticPipError):
662+
"""Raised when the downloader receives fewer bytes than advertised
663+
in the Content-Length header."""
664+
665+
reference = "incomplete-download-error"
666+
667+
def __init__(
668+
self, link: str, resume_incomplete: bool, resume_attempts: int
669+
) -> None:
670+
if resume_incomplete:
671+
message = (
672+
"Download failed after {} attempts because not enough bytes are"
673+
" received. The incomplete file has been cleaned up."
674+
).format(resume_attempts)
675+
hint = "Use --incomplete-download-retries to configure resume retry limit."
676+
else:
677+
message = (
678+
"Download failed because not enough bytes are received."
679+
" The incomplete file has been cleaned up."
680+
)
681+
hint = (
682+
"Use --incomplete-downloads=resume to make pip retry failed download."
683+
)
684+
685+
super().__init__(
686+
message=message,
687+
context="File: {}\n"
688+
"Resume failed download: {}\n"
689+
"Resume retry limit: {}".format(link, resume_incomplete, resume_attempts),
690+
hint_stmt=hint,
691+
note_stmt="This is an issue with network connectivity, not pip.",
692+
)

src/pip/_internal/network/download.py

+4-15
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from pip._vendor.requests.models import CONTENT_CHUNK_SIZE, Response
1111

1212
from pip._internal.cli.progress_bars import get_download_progress_renderer
13-
from pip._internal.exceptions import NetworkConnectionError
13+
from pip._internal.exceptions import IncompleteDownloadError, NetworkConnectionError
1414
from pip._internal.models.index import PyPI
1515
from pip._internal.models.link import Link
1616
from pip._internal.network.cache import is_from_cache
@@ -228,21 +228,10 @@ def __call__(self, link: Link, location: str) -> Tuple[str, str]:
228228
content_file.write(chunk)
229229

230230
if total_length is not None and bytes_received < total_length:
231-
if self._resume_incomplete:
232-
logger.critical(
233-
"Failed to download %s after %d resumption attempts.",
234-
link,
235-
self._resume_attempts,
236-
)
237-
else:
238-
logger.critical(
239-
"Failed to download %s."
240-
" Set --incomplete-downloads=resume to automatically"
241-
"resume incomplete download.",
242-
link,
243-
)
244231
os.remove(filepath)
245-
raise RuntimeError("Incomplete download")
232+
raise IncompleteDownloadError(
233+
str(link), self._resume_incomplete, self._resume_attempts
234+
)
246235

247236
content_type = resp.headers.get("Content-Type", "")
248237
return filepath, content_type

0 commit comments

Comments
 (0)