feat: Enhance update check and download processes with safety timeouts and logging

This commit is contained in:
claudi 2026-01-30 13:09:50 +01:00
parent f4eb511a1c
commit 4ab44c83ba
2 changed files with 156 additions and 51 deletions

View file

@ -8,6 +8,7 @@ import asyncio
import hashlib
import json
import logging
import socket
from dataclasses import dataclass
from datetime import datetime, timedelta
from pathlib import Path
@ -144,9 +145,13 @@ class UpdateManager:
Returns:
Release object if newer version available, None otherwise
"""
logger.debug(f"check_for_updates() called, current version: {self.current_version}")
# Try cache first
logger.debug("Checking cache...")
cached = self._load_cache()
if cached:
logger.debug("Found cached release")
release_data = cached.get("release")
if release_data:
version = release_data["tag_name"].lstrip("v")
@ -156,6 +161,7 @@ class UpdateManager:
return Release(**release_data)
# Fetch from API
logger.debug("Fetching from API...")
try:
logger.info(f"Checking for updates from {self.api_endpoint}")
@ -198,19 +204,40 @@ class UpdateManager:
"""
try:
logger.debug(f"Fetching release from {self.api_endpoint}")
# Use aggressive timeout: 5 seconds for connection, 5 seconds for read
with urlopen(self.api_endpoint, timeout=5) as response:
data = json.loads(response.read())
return {
"tag_name": data["tag_name"],
"name": data["name"],
"version": data["tag_name"].lstrip("v"),
"body": data["body"],
"assets": data.get("assets", []),
"published_at": data.get("published_at", ""),
}
# Set socket timeout to prevent hanging
old_timeout = socket.getdefaulttimeout()
socket.setdefaulttimeout(5)
try:
logger.debug("Opening URL connection...")
with urlopen(self.api_endpoint, timeout=5) as response:
logger.debug(f"Response status: {response.status}, reading data...")
response_data = response.read()
logger.debug(f"Read {len(response_data)} bytes, parsing JSON...")
data = json.loads(response_data)
logger.info(f"Successfully fetched release: {data.get('tag_name', 'unknown')}")
return {
"tag_name": data["tag_name"],
"name": data["name"],
"version": data["tag_name"].lstrip("v"),
"body": data["body"],
"assets": data.get("assets", []),
"published_at": data.get("published_at", ""),
}
finally:
socket.setdefaulttimeout(old_timeout)
except socket.timeout as e:
logger.error(f"Socket timeout (5s) connecting to {self.api_endpoint}")
return None
except TimeoutError as e:
logger.error(f"Timeout error: {e}")
return None
except Exception as e:
logger.error(f"Failed to fetch release: {type(e).__name__}: {e}")
import traceback
logger.debug(traceback.format_exc())
return None
async def download_update(