Skip to content

Commit 487536e

Browse files
fix(updater): treat GitHub releases 404 as no update
GitHub returns HTTP 404 for /releases/latest when no release exists. Previously this logged at INFO and emitted failed; now return None so check completes as up-to-date and cooldown applies. Made-with: Cursor
1 parent 16cf39b commit 487536e

2 files changed

Lines changed: 57 additions & 2 deletions

File tree

src/dbs_annotator/utils/updater.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,19 @@ def _fetch_latest_release(self) -> ReleaseInfo | None:
117117
"User-Agent": f"DBSAnnotator/{self._current_version}",
118118
},
119119
)
120-
with urllib.request.urlopen(request, timeout=self._timeout) as response:
121-
payload = json.loads(response.read().decode("utf-8"))
120+
try:
121+
with urllib.request.urlopen(request, timeout=self._timeout) as response:
122+
payload = json.loads(response.read().decode("utf-8"))
123+
except urllib.error.HTTPError as exc:
124+
# GitHub returns 404 when repo has no published releases (or repo missing).
125+
if exc.code == 404:
126+
logger.debug(
127+
"No GitHub releases/latest for %s (HTTP %s); treat as no update",
128+
self._repo,
129+
exc.code,
130+
)
131+
return None
132+
raise
122133

123134
tag = str(payload.get("tag_name", ""))
124135
if not tag:

tests/unit/test_updater.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
"""Tests for :mod:`dbs_annotator.utils.updater`."""
2+
3+
from __future__ import annotations
4+
5+
import io
6+
import urllib.error
7+
from unittest.mock import patch
8+
9+
import pytest
10+
11+
from dbs_annotator.utils.updater import _CheckSignals, _CheckWorker
12+
13+
14+
def test_fetch_latest_release_http_404_returns_none() -> None:
15+
"""GitHub ``/releases/latest`` → 404 when nothing published; no exception."""
16+
signals = _CheckSignals()
17+
worker = _CheckWorker("owner/repo", "1.0.0", 10.0, signals)
18+
err = urllib.error.HTTPError(
19+
"https://api.github.com/repos/owner/repo/releases/latest",
20+
404,
21+
"Not Found",
22+
{},
23+
io.BytesIO(b""),
24+
)
25+
with patch("urllib.request.urlopen", side_effect=err):
26+
assert worker._fetch_latest_release() is None
27+
28+
29+
@pytest.mark.parametrize("code", [403, 500, 502])
30+
def test_fetch_latest_release_other_http_raises(code: int) -> None:
31+
signals = _CheckSignals()
32+
worker = _CheckWorker("owner/repo", "1.0.0", 10.0, signals)
33+
err = urllib.error.HTTPError(
34+
"https://example.com",
35+
code,
36+
"err",
37+
{},
38+
io.BytesIO(b""),
39+
)
40+
with patch("urllib.request.urlopen", side_effect=err), pytest.raises(
41+
urllib.error.HTTPError
42+
) as ctx:
43+
worker._fetch_latest_release()
44+
assert ctx.value.code == code

0 commit comments

Comments
 (0)