From ffef6313d431592d39cc718175b527fc5ae16e29 Mon Sep 17 00:00:00 2001 From: Michel Roegl-Brunner Date: Fri, 24 Oct 2025 22:23:59 +0200 Subject: [PATCH] Add error reporting for GitHub rate limit errors - Add specific error handling for GitHub API rate limit (403) errors - Create RateLimitError with proper error name for identification - Store last sync error and error time in settings for UI display - Add error status display in autosync settings modal - Show user-friendly error messages with GitHub token suggestion - Clear error status on successful sync - Update both GitHubJsonService and GitHubService with rate limit error handling This provides better user feedback when GitHub API rate limits are exceeded and guides users to set up a GitHub token for higher rate limits. --- src/app/_components/GeneralSettingsModal.tsx | 44 +++++++-------- src/app/api/settings/auto-sync/route.ts | 15 ++++-- src/server/services/autoSyncService.js | 57 ++++++++++++++++---- src/server/services/github.ts | 7 ++- src/server/services/githubJsonService.ts | 11 ++-- 5 files changed, 92 insertions(+), 42 deletions(-) diff --git a/src/app/_components/GeneralSettingsModal.tsx b/src/app/_components/GeneralSettingsModal.tsx index 7cf3b9f..9a5debb 100644 --- a/src/app/_components/GeneralSettingsModal.tsx +++ b/src/app/_components/GeneralSettingsModal.tsx @@ -46,6 +46,8 @@ export function GeneralSettingsModal({ isOpen, onClose }: GeneralSettingsModalPr const [appriseUrls, setAppriseUrls] = useState([]); const [appriseUrlsText, setAppriseUrlsText] = useState(''); const [lastAutoSync, setLastAutoSync] = useState(''); + const [lastAutoSyncError, setLastAutoSyncError] = useState(null); + const [lastAutoSyncErrorTime, setLastAutoSyncErrorTime] = useState(null); const [cronValidationError, setCronValidationError] = useState(''); // Load existing settings when modal opens @@ -311,6 +313,8 @@ export function GeneralSettingsModal({ isOpen, onClose }: GeneralSettingsModalPr setAppriseUrls(settings.appriseUrls ?? []); setAppriseUrlsText((settings.appriseUrls ?? []).join('\n')); setLastAutoSync(settings.lastAutoSync ?? ''); + setLastAutoSyncError(settings.lastAutoSyncError ?? null); + setLastAutoSyncErrorTime(settings.lastAutoSyncErrorTime ?? null); } } } catch (error) { @@ -322,17 +326,6 @@ export function GeneralSettingsModal({ isOpen, onClose }: GeneralSettingsModalPr setIsSaving(true); setMessage(null); - console.log('Saving auto-sync settings:', { - autoSyncEnabled, - syncIntervalType, - syncIntervalPredefined, - syncIntervalCron, - autoDownloadNew, - autoUpdateExisting, - notificationEnabled, - appriseUrls - }); - try { const response = await fetch('/api/settings/auto-sync', { method: 'POST', @@ -348,17 +341,12 @@ export function GeneralSettingsModal({ isOpen, onClose }: GeneralSettingsModalPr appriseUrls: appriseUrls }) }); - - console.log('API response status:', response.status); if (response.ok) { - const result = await response.json(); - console.log('API response data:', result); setMessage({ type: 'success', text: 'Auto-sync settings saved successfully!' }); setTimeout(() => setMessage(null), 3000); } else { const errorData = await response.json(); - console.error('API error:', errorData); setMessage({ type: 'error', text: errorData.error ?? 'Failed to save auto-sync settings' }); } } catch (error) { @@ -817,7 +805,6 @@ export function GeneralSettingsModal({ isOpen, onClose }: GeneralSettingsModalPr { - console.log('Toggle changed to:', checked); setAutoSyncEnabled(checked); // Auto-save when toggle changes @@ -843,14 +830,10 @@ export function GeneralSettingsModal({ isOpen, onClose }: GeneralSettingsModalPr }); if (response.ok) { - console.log('Auto-sync toggle saved successfully'); // Update local state to reflect the effective sync interval type if (effectiveSyncIntervalType !== syncIntervalType) { setSyncIntervalType(effectiveSyncIntervalType); } - } else { - const errorData = await response.json(); - console.error('Failed to save auto-sync toggle:', errorData); } } catch (error) { console.error('Error saving auto-sync toggle:', error); @@ -1047,6 +1030,25 @@ export function GeneralSettingsModal({ isOpen, onClose }: GeneralSettingsModalPr )} + {lastAutoSyncError && ( +
+
+ + + +
+

Last sync error:

+

{lastAutoSyncError}

+ {lastAutoSyncErrorTime && ( +

+ {new Date(lastAutoSyncErrorTime).toLocaleString()} +

+ )} +
+
+
+ )} +