mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-03-21 21:22:11 -03:00
fix(updates): avoid network stack traces offline
This commit is contained in:
@@ -5,12 +5,16 @@ import git
|
||||
import zipfile
|
||||
import shutil
|
||||
import tempfile
|
||||
from aiohttp import web
|
||||
import asyncio
|
||||
from aiohttp import web, ClientError
|
||||
from typing import Dict, List
|
||||
from ..services.downloader import get_downloader
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
NETWORK_EXCEPTIONS = (ClientError, OSError, asyncio.TimeoutError)
|
||||
|
||||
|
||||
class UpdateRoutes:
|
||||
"""Routes for handling plugin update checks"""
|
||||
|
||||
@@ -63,6 +67,12 @@ class UpdateRoutes:
|
||||
'nightly': nightly
|
||||
})
|
||||
|
||||
except NETWORK_EXCEPTIONS as e:
|
||||
logger.warning("Network unavailable during update check: %s", e)
|
||||
return web.json_response({
|
||||
'success': False,
|
||||
'error': 'Network unavailable for update check'
|
||||
})
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to check for updates: {e}", exc_info=True)
|
||||
return web.json_response({
|
||||
@@ -283,6 +293,9 @@ class UpdateRoutes:
|
||||
|
||||
return version, changelog
|
||||
|
||||
except NETWORK_EXCEPTIONS as e:
|
||||
logger.warning("Unable to reach GitHub for nightly version: %s", e)
|
||||
return "main", []
|
||||
except Exception as e:
|
||||
logger.error(f"Error fetching nightly version: {e}", exc_info=True)
|
||||
return "main", []
|
||||
@@ -448,6 +461,9 @@ class UpdateRoutes:
|
||||
|
||||
return version, changelog
|
||||
|
||||
except NETWORK_EXCEPTIONS as e:
|
||||
logger.warning("Unable to reach GitHub for release info: %s", e)
|
||||
return "v0.0.0", []
|
||||
except Exception as e:
|
||||
logger.error(f"Error fetching remote version: {e}", exc_info=True)
|
||||
return "v0.0.0", []
|
||||
|
||||
@@ -82,11 +82,15 @@ export class UpdateService {
|
||||
}
|
||||
}
|
||||
|
||||
async checkForUpdates() {
|
||||
async checkForUpdates({ force = false } = {}) {
|
||||
if (!force && !this.updateNotificationsEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if we should perform an update check
|
||||
const now = Date.now();
|
||||
const forceCheck = this.lastCheckTime === 0;
|
||||
|
||||
const forceCheck = force || this.lastCheckTime === 0;
|
||||
|
||||
if (!forceCheck && now - this.lastCheckTime < this.updateCheckInterval) {
|
||||
// If we already have update info, just update the UI
|
||||
if (this.updateAvailable) {
|
||||
@@ -94,7 +98,7 @@ export class UpdateService {
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
// Call backend API to check for updates with nightly flag
|
||||
const response = await fetch(`/api/lm/check-updates?nightly=${this.nightlyMode}`);
|
||||
@@ -435,8 +439,7 @@ export class UpdateService {
|
||||
}
|
||||
|
||||
async manualCheckForUpdates() {
|
||||
this.lastCheckTime = 0; // Reset last check time to force check
|
||||
await this.checkForUpdates();
|
||||
await this.checkForUpdates({ force: true });
|
||||
// Ensure badge visibility is updated after manual check
|
||||
this.updateBadgeVisibility();
|
||||
}
|
||||
|
||||
45
tests/frontend/managers/updateService.test.js
Normal file
45
tests/frontend/managers/updateService.test.js
Normal file
@@ -0,0 +1,45 @@
|
||||
import { describe, beforeEach, afterEach, expect, it, vi } from 'vitest';
|
||||
import { UpdateService } from '../../../static/js/managers/UpdateService.js';
|
||||
|
||||
function createFetchResponse(payload) {
|
||||
return {
|
||||
json: vi.fn().mockResolvedValue(payload)
|
||||
};
|
||||
}
|
||||
|
||||
describe('UpdateService passive checks', () => {
|
||||
let service;
|
||||
let fetchMock;
|
||||
|
||||
beforeEach(() => {
|
||||
fetchMock = vi.fn().mockResolvedValue(createFetchResponse({
|
||||
success: true,
|
||||
current_version: 'v1.0.0',
|
||||
latest_version: 'v1.0.0',
|
||||
git_info: { short_hash: 'abc123' }
|
||||
}));
|
||||
global.fetch = fetchMock;
|
||||
|
||||
service = new UpdateService();
|
||||
service.updateNotificationsEnabled = false;
|
||||
service.lastCheckTime = 0;
|
||||
service.nightlyMode = false;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
delete global.fetch;
|
||||
});
|
||||
|
||||
it('skips passive update checks when notifications are disabled', async () => {
|
||||
await service.checkForUpdates();
|
||||
|
||||
expect(fetchMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('allows manual checks even when notifications are disabled', async () => {
|
||||
await service.checkForUpdates({ force: true });
|
||||
|
||||
expect(fetchMock).toHaveBeenCalledTimes(1);
|
||||
expect(fetchMock).toHaveBeenCalledWith('/api/lm/check-updates?nightly=false');
|
||||
});
|
||||
});
|
||||
59
tests/routes/test_update_routes.py
Normal file
59
tests/routes/test_update_routes.py
Normal file
@@ -0,0 +1,59 @@
|
||||
import logging
|
||||
from aiohttp import ClientError
|
||||
import pytest
|
||||
|
||||
from py.routes import update_routes
|
||||
|
||||
|
||||
class OfflineDownloader:
|
||||
async def make_request(self, *_, **__):
|
||||
return False, "Cannot connect to host"
|
||||
|
||||
|
||||
class RaisingDownloader:
|
||||
async def make_request(self, *_, **__):
|
||||
raise ClientError("offline")
|
||||
|
||||
|
||||
async def _stub_downloader(instance):
|
||||
return instance
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_get_remote_version_offline_logs_without_traceback(monkeypatch, caplog):
|
||||
caplog.set_level(logging.WARNING)
|
||||
monkeypatch.setattr(update_routes, "get_downloader", lambda: _stub_downloader(OfflineDownloader()))
|
||||
|
||||
version, changelog = await update_routes.UpdateRoutes._get_remote_version()
|
||||
|
||||
assert version == "v0.0.0"
|
||||
assert changelog == []
|
||||
assert "Failed to fetch GitHub release" in caplog.text
|
||||
assert "Cannot connect to host" in caplog.text
|
||||
assert "Traceback" not in caplog.text
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_get_remote_version_network_error_logs_warning(monkeypatch, caplog):
|
||||
caplog.set_level(logging.WARNING)
|
||||
monkeypatch.setattr(update_routes, "get_downloader", lambda: _stub_downloader(RaisingDownloader()))
|
||||
|
||||
version, changelog = await update_routes.UpdateRoutes._get_remote_version()
|
||||
|
||||
assert version == "v0.0.0"
|
||||
assert changelog == []
|
||||
assert "Unable to reach GitHub for release info" in caplog.text
|
||||
assert "Traceback" not in caplog.text
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_get_nightly_version_network_error_logs_warning(monkeypatch, caplog):
|
||||
caplog.set_level(logging.WARNING)
|
||||
monkeypatch.setattr(update_routes, "get_downloader", lambda: _stub_downloader(RaisingDownloader()))
|
||||
|
||||
version, changelog = await update_routes.UpdateRoutes._get_nightly_version()
|
||||
|
||||
assert version == "main"
|
||||
assert changelog == []
|
||||
assert "Unable to reach GitHub for nightly version" in caplog.text
|
||||
assert "Traceback" not in caplog.text
|
||||
Reference in New Issue
Block a user