From 4ccfe93a8d5253383616df0cce6daba5c6346820 Mon Sep 17 00:00:00 2001 From: jdotc1 <138259519+jdotc1@users.noreply.github.com> Date: Wed, 14 Oct 2026 17:48:15 -0400 Subject: [PATCH 1/2] Propagate failures before download publication completes Assisted-by: OpenAI Codex Signed-off-by: jdotc1 <138259519+jdotc1@users.noreply.github.com> --- monai/apps/utils.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/monai/apps/utils.py b/monai/apps/utils.py index b15b0c1969c..695e326d11f 100644 --- a/monai/apps/utils.py +++ b/monai/apps/utils.py @@ -244,6 +244,7 @@ def download_url( raise HashCheckError(f"{hash_type} hash check of existing file failed: {filepath=}, expected {hash_type=}.") logger.info(f"File exists: {filepath}, skipped downloading.") return + download_complete = False try: with tempfile.TemporaryDirectory() as tmp_dir: tmp_name = Path(tmp_dir, _basename(filepath)) @@ -281,8 +282,11 @@ def download_url( if file_dir: os.makedirs(file_dir, exist_ok=True) shutil.move(f"{tmp_name}", f"{filepath}") # copy the downloaded to a user-specified cache. + download_complete = True except (PermissionError, NotADirectoryError): # project-monai/monai issue #3613 #3757 for windows - pass + # Retain only the historical post-publication cleanup exemption. + if not download_complete: + raise logger.info(f"Downloaded: {filepath}") From 8b50ee67b356764aa85c6b429f9548762dfc4ad9 Mon Sep 17 00:00:00 2001 From: jdotc1 <138259519+jdotc1@users.noreply.github.com> Date: Fri, 16 Oct 2026 18:02:46 -0400 Subject: [PATCH 2/2] DOC: Clarify download publication exceptions Assisted-by: OpenAI Codex Signed-off-by: jdotc1 <138259519+jdotc1@users.noreply.github.com> --- monai/apps/utils.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/monai/apps/utils.py b/monai/apps/utils.py index 695e326d11f..2e16fc73e19 100644 --- a/monai/apps/utils.py +++ b/monai/apps/utils.py @@ -234,6 +234,12 @@ def download_url( ContentTooShortError: See urllib.request.urlretrieve. IOError: See urllib.request.urlretrieve. HashCheckError: When the hash validation of the ``url`` downloaded file fails. + PermissionError: When access is denied before the downloaded file has been + moved to ``filepath``, including during destination setup or the move. + NotADirectoryError: When a path component is not a directory before the + downloaded file has been moved to ``filepath``. These filesystem + exceptions remain suppressed during temporary-directory cleanup after + a successful move. """ if not filepath: filepath = Path(".", _basename(url)).resolve()