fix(update): treat an incomplete Docker Hub response as unreadable

followed_tags caught OSError, ValueError, KeyError and RuntimeError, but
http.client.IncompleteRead, BadStatusLine and LineTooLong derive from
http.client.HTTPException only. One truncated digest response therefore
escaped to collect_updates (docker.py:344, no try) and aborted the whole
Docker update run instead of printing the follow warning for that image.
Every other fetch site of the updater already catches HTTPException
(docker.py, pip.py).

Reported by CodeRabbit on #1370.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
kevinveenbirkenbachandClaude Opus 5.5 committed 2026-11-04 19:16:16 +01:00
1 parent 68c5f6ecc4
commit c068e44d1b
2 files changed
+23 -1

No files matched your search

@@ -1,6 +1,7 @@
from __future__ import annotations
import contextlib
import http.client
import io
import json
import unittest
@@ -54,6 +55,20 @@ class TestFollowedTags(unittest.TestCase):
self.assertEqual(found, [])
self.assertIn("WARN fedora:44", stderr.getvalue())
def test_an_incomplete_response_proposes_nothing_and_says_so(self) -> None:
stderr = io.StringIO()
with (
mock.patch(
"utils.update.follow.get",
side_effect=http.client.IncompleteRead(b"{", 120),
),
contextlib.redirect_stderr(stderr),
):
found = followed_tags("fedora", list(FEDORA), {"follow": "latest"}, "44")
self.assertEqual(found, [])
self.assertIn("WARN fedora:44", stderr.getvalue())
self.assertIn("IncompleteRead", stderr.getvalue())
def test_a_rate_limited_digest_is_retried(self) -> None:
limited = urllib.error.HTTPError("url", 429, "Too Many Requests", {}, None)
body = json.dumps({"digest": "sha256:45"}).encode()
+8 -1
View File
@@ -9,6 +9,7 @@ rawhide) point elsewhere.
from __future__ import annotations
import http.client
import json
import sys
import time
@@ -69,7 +70,13 @@ def followed_tags(
try:
target = tag_digest(image, str(follow))
kept = [tag for tag in newer if tag_digest(image, tag) == target]
except (OSError, ValueError, KeyError, RuntimeError) as exc:
except (
OSError,
ValueError,
KeyError,
RuntimeError,
http.client.HTTPException,
) as exc:
print(
f"[follow] WARN {image}:{current}: Docker Hub digests unreadable "
f"({type(exc).__name__}: {exc}); proposing nothing",