diff --git a/src/backend/ssh/terminal.ts b/src/backend/ssh/terminal.ts index 22d8e024..e34beff8 100644 --- a/src/backend/ssh/terminal.ts +++ b/src/backend/ssh/terminal.ts @@ -1503,15 +1503,24 @@ wss.on("connection", async (ws: WebSocket, req) => { } }); - stream.on("close", () => { + stream.on("close", (code: number | null) => { const session = sessionManager.getSession(boundSessionId); if (session?.attachedWs?.readyState === WebSocket.OPEN) { - session.attachedWs.send( - JSON.stringify({ - type: "disconnected", - message: "Connection lost", - }), - ); + if (code != null) { + session.attachedWs.send( + JSON.stringify({ + type: "session_ended", + code, + }), + ); + } else { + session.attachedWs.send( + JSON.stringify({ + type: "disconnected", + message: "Connection lost", + }), + ); + } } if (boundSessionId) { sessionManager.destroySession(boundSessionId); diff --git a/src/locales/en.json b/src/locales/en.json index 79564c6a..340bd021 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -1676,6 +1676,7 @@ "automaticFallback": "Automatically trying {{method}} authentication...", "totpTimeout": "TOTP verification timeout. Please reconnect.", "passwordTimeout": "Password verification timeout. Please reconnect.", + "sessionEnded": "Session ended.", "connectionRejected": "Connection rejected by server. Please check your authentication and network configuration.", "hostKeyRejected": "SSH host key verification rejected. Connection cancelled.", "sessionTakenOver": "Session was opened in another tab. Reconnecting...", diff --git a/src/ui/desktop/apps/features/terminal/Terminal.tsx b/src/ui/desktop/apps/features/terminal/Terminal.tsx index 1f32e98f..e6469bd0 100644 --- a/src/ui/desktop/apps/features/terminal/Terminal.tsx +++ b/src/ui/desktop/apps/features/terminal/Terminal.tsx @@ -1187,6 +1187,14 @@ const TerminalInner = forwardRef( ); } }, 100); + } else if (msg.type === "session_ended") { + wasDisconnectedBySSH.current = true; + setIsConnected(false); + setIsConnecting(false); + shouldNotReconnectRef.current = true; + if (onClose) { + onClose(); + } } else if (msg.type === "disconnected") { wasDisconnectedBySSH.current = true; shouldNotReconnectRef.current = true; diff --git a/src/ui/mobile/apps/terminal/Terminal.tsx b/src/ui/mobile/apps/terminal/Terminal.tsx index 9ce4fa83..73a573c3 100644 --- a/src/ui/mobile/apps/terminal/Terminal.tsx +++ b/src/ui/mobile/apps/terminal/Terminal.tsx @@ -729,6 +729,13 @@ const TerminalInner = forwardRef( ); } }, 100); + } else if (msg.type === "session_ended") { + wasDisconnectedBySSH.current = true; + shouldNotReconnectRef.current = true; + isConnectingRef.current = false; + setIsConnected(false); + setIsConnecting(false); + updateConnectionError(t("terminal.sessionEnded")); } else if (msg.type === "disconnected") { wasDisconnectedBySSH.current = true; isConnectingRef.current = false;