mirror of
https://github.com/smittix/intercept.git
synced 2026-04-24 06:40:00 -07:00
Handle transient network suspension in frontend polling and SSE
This commit is contained in:
@@ -7,6 +7,7 @@ const AlertCenter = (function() {
|
||||
let rules = [];
|
||||
let eventSource = null;
|
||||
let reconnectTimer = null;
|
||||
let lastConnectionWarningAt = 0;
|
||||
|
||||
function init() {
|
||||
loadRules();
|
||||
@@ -31,7 +32,14 @@ const AlertCenter = (function() {
|
||||
};
|
||||
|
||||
eventSource.onerror = function() {
|
||||
console.warn('[Alerts] SSE connection error');
|
||||
const now = Date.now();
|
||||
const offline = (typeof window.isOffline === 'function' && window.isOffline()) ||
|
||||
(typeof navigator !== 'undefined' && navigator.onLine === false);
|
||||
const shouldLog = !offline && !document.hidden && (now - lastConnectionWarningAt) > 15000;
|
||||
if (shouldLog) {
|
||||
lastConnectionWarningAt = now;
|
||||
console.warn('[Alerts] SSE connection error; retrying');
|
||||
}
|
||||
if (reconnectTimer) clearTimeout(reconnectTimer);
|
||||
reconnectTimer = setTimeout(connect, 2500);
|
||||
};
|
||||
|
||||
@@ -92,8 +92,9 @@ const RunState = (function() {
|
||||
renderHealth(data);
|
||||
} catch (err) {
|
||||
renderHealth(null, err);
|
||||
const transient = isTransientFailure(err);
|
||||
const now = Date.now();
|
||||
if (typeof reportActionableError === 'function' && (now - lastErrorToastAt) > 30000) {
|
||||
if (!transient && typeof reportActionableError === 'function' && (now - lastErrorToastAt) > 30000) {
|
||||
lastErrorToastAt = now;
|
||||
reportActionableError('Run State', err, { persistent: false });
|
||||
}
|
||||
@@ -214,6 +215,17 @@ const RunState = (function() {
|
||||
return String(err);
|
||||
}
|
||||
|
||||
function isTransientFailure(err) {
|
||||
if (typeof window.isTransientOrOffline === 'function' && window.isTransientOrOffline(err)) {
|
||||
return true;
|
||||
}
|
||||
if (typeof navigator !== 'undefined' && navigator.onLine === false) {
|
||||
return true;
|
||||
}
|
||||
const text = extractMessage(err).toLowerCase();
|
||||
return text.includes('failed to fetch') || text.includes('network') || text.includes('timeout');
|
||||
}
|
||||
|
||||
function getLastHealth() {
|
||||
return lastHealth;
|
||||
}
|
||||
|
||||
@@ -208,9 +208,31 @@ const AppFeedback = (function() {
|
||||
return state;
|
||||
}
|
||||
|
||||
function isOffline() {
|
||||
return typeof navigator !== 'undefined' && navigator.onLine === false;
|
||||
}
|
||||
|
||||
function isTransientNetworkError(error) {
|
||||
const text = String(extractMessage(error) || '').toLowerCase();
|
||||
if (!text) return false;
|
||||
|
||||
return text.includes('networkerror') ||
|
||||
text.includes('failed to fetch') ||
|
||||
text.includes('network request failed') ||
|
||||
text.includes('load failed') ||
|
||||
text.includes('err_network_io_suspended') ||
|
||||
text.includes('network io suspended') ||
|
||||
text.includes('the network connection was lost') ||
|
||||
text.includes('connection reset') ||
|
||||
text.includes('timeout');
|
||||
}
|
||||
|
||||
function isTransientOrOffline(error) {
|
||||
return isOffline() || isTransientNetworkError(error);
|
||||
}
|
||||
|
||||
function isNetworkError(message) {
|
||||
const text = String(message || '').toLowerCase();
|
||||
return text.includes('networkerror') || text.includes('failed to fetch') || text.includes('timeout');
|
||||
return isTransientNetworkError(message);
|
||||
}
|
||||
|
||||
function isSettingsError(message) {
|
||||
@@ -224,6 +246,9 @@ const AppFeedback = (function() {
|
||||
reportError,
|
||||
removeToast,
|
||||
renderCollectionState,
|
||||
isOffline,
|
||||
isTransientNetworkError,
|
||||
isTransientOrOffline,
|
||||
};
|
||||
})();
|
||||
|
||||
@@ -243,6 +268,18 @@ window.renderCollectionState = function(container, options) {
|
||||
return AppFeedback.renderCollectionState(container, options);
|
||||
};
|
||||
|
||||
window.isOffline = function() {
|
||||
return AppFeedback.isOffline();
|
||||
};
|
||||
|
||||
window.isTransientNetworkError = function(error) {
|
||||
return AppFeedback.isTransientNetworkError(error);
|
||||
};
|
||||
|
||||
window.isTransientOrOffline = function(error) {
|
||||
return AppFeedback.isTransientOrOffline(error);
|
||||
};
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
AppFeedback.init();
|
||||
});
|
||||
|
||||
@@ -5655,10 +5655,19 @@
|
||||
renderSdrStatus(devices);
|
||||
})
|
||||
.catch(err => {
|
||||
console.error('Failed to fetch SDR status:', err);
|
||||
const transient = (typeof window.isTransientOrOffline === 'function' && window.isTransientOrOffline(err)) ||
|
||||
(typeof navigator !== 'undefined' && navigator.onLine === false) ||
|
||||
/failed to fetch|network io suspended|networkerror|timeout/i.test(String((err && err.message) || err || ''));
|
||||
if (!transient) {
|
||||
console.error('Failed to fetch SDR status:', err);
|
||||
}
|
||||
const container = document.getElementById('sdrStatusList');
|
||||
if (container) {
|
||||
container.innerHTML = '<div style="padding: 8px; color: #ff6666; font-size: 11px; text-align: center;">Error loading status</div>';
|
||||
if (transient) {
|
||||
container.innerHTML = '<div style="padding: 8px; color: #888; font-size: 11px; text-align: center;">Status temporarily unavailable</div>';
|
||||
} else {
|
||||
container.innerHTML = '<div style="padding: 8px; color: #ff6666; font-size: 11px; text-align: center;">Error loading status</div>';
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -971,7 +971,12 @@
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Position update error:', err);
|
||||
const transient = (typeof window.isTransientOrOffline === 'function' && window.isTransientOrOffline(err)) ||
|
||||
(typeof navigator !== 'undefined' && navigator.onLine === false) ||
|
||||
/failed to fetch|network io suspended|networkerror|timeout/i.test(String((err && err.message) || err || ''));
|
||||
if (!transient) {
|
||||
console.error('Position update error:', err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user