mirror of
https://github.com/Shik3i/KoalaSync.git
synced 2026-07-26 12:08:15 +00:00
fix(lazy-connect): harden connection lifecycle against race conditions and edge cases
- Prevent concurrent connect() by removing isConnecting reset from forceDisconnect(); the guard in connect() now reliably blocks re-entry since no external caller can defeat it. - Reset isConnecting at end of connect() so subsequent calls can proceed without waiting for the async '40' handler. - Clear connectIntent and cancel reconnect timer on server ERROR when no currentRoom exists, preventing infinite reconnect loops after failed join attempts (e.g. wrong password via invite link). - Move connectIntent assignment after !roomId guard in WEB_JOIN_REQUEST to avoid clobbering existing intent on invalid input. - Broadcast JOIN_STATUS failure to popup and bridge tabs when WEB_JOIN_REQUEST receives an invalid room ID, so the website join page receives feedback instead of hanging forever. - Clear joinBtnTimeout on CONNECTION_STATUS connected/disconnected to avoid stale timeout error messages in the popup.
This commit is contained in:
+20
-3
@@ -343,7 +343,6 @@ function forceDisconnect() {
|
||||
socket = null;
|
||||
}
|
||||
currentServerUrl = null;
|
||||
isConnecting = false;
|
||||
isNamespaceJoined = false;
|
||||
isForceSyncInitiator = false;
|
||||
expectedAcksCount = 0;
|
||||
@@ -606,6 +605,8 @@ async function connect() {
|
||||
addLog('WebSocket Error: Connection failed', logType);
|
||||
};
|
||||
|
||||
isConnecting = false;
|
||||
|
||||
} catch (e) {
|
||||
isConnecting = false;
|
||||
const logType = reconnectAttempts > 1 ? 'error' : 'warn';
|
||||
@@ -856,6 +857,14 @@ function handleServerEvent(event, data) {
|
||||
break;
|
||||
case EVENTS.ERROR:
|
||||
isConnecting = false;
|
||||
// If we get a server error before successfully joining a room,
|
||||
// clear connectIntent to prevent an infinite reconnect loop.
|
||||
if (!currentRoom) {
|
||||
connectIntent = false;
|
||||
if (reconnectTimer) { clearTimeout(reconnectTimer); reconnectTimer = null; }
|
||||
reconnectAttempts = 0;
|
||||
reconnectFailed = false;
|
||||
}
|
||||
broadcastConnectionStatus('disconnected');
|
||||
addLog(`Server Error: ${data.message}`, 'error');
|
||||
chrome.storage.local.get(['browserNotifications', 'locale'], async (settings) => {
|
||||
@@ -1554,8 +1563,16 @@ async function handleAsyncMessage(message, sender, sendResponse) {
|
||||
} else if (message.type === 'WEB_JOIN_REQUEST') {
|
||||
const { roomId: rawRoomId, password, useCustomServer, serverUrl } = message;
|
||||
const roomId = typeof rawRoomId === 'string' ? rawRoomId.replace(/[^a-zA-Z0-9\-]/g, '') : '';
|
||||
connectIntent = !!roomId;
|
||||
if (!roomId) { sendResponse({ error: 'invalid_room_id' }); return; }
|
||||
if (!roomId) {
|
||||
const errMsg = { type: 'JOIN_STATUS', success: false, message: 'Invalid room ID' };
|
||||
chrome.runtime.sendMessage(errMsg).catch(() => {});
|
||||
chrome.tabs.query({}, (tabs) => {
|
||||
tabs.forEach(tab => chrome.tabs.sendMessage(tab.id, errMsg).catch(() => {}));
|
||||
});
|
||||
sendResponse({ status: 'invalid_room_id' });
|
||||
return;
|
||||
}
|
||||
connectIntent = true;
|
||||
chrome.storage.local.set({
|
||||
roomId,
|
||||
password,
|
||||
|
||||
@@ -1623,6 +1623,9 @@ chrome.runtime.onMessage.addListener((msg) => {
|
||||
updatePeerList(msg.peers);
|
||||
if (msg.peers) detectPeerChanges(msg.peers);
|
||||
} else if (msg.type === 'CONNECTION_STATUS') {
|
||||
if (msg.status === 'connected' || msg.status === 'disconnected') {
|
||||
if (joinBtnTimeout) { clearTimeout(joinBtnTimeout); joinBtnTimeout = null; }
|
||||
}
|
||||
if (msg.status === 'connected') {
|
||||
clearConnectionErrorTimer();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user