Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions opennow-stable/src/renderer/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,7 @@ export function App(): JSX.Element {
const hasInitializedRef = useRef(false);
const regionsRequestRef = useRef(0);
const launchInFlightRef = useRef(false);
const launchAbortRef = useRef(false);
const streamStatusRef = useRef<StreamStatus>(streamStatus);
const exitPromptResolverRef = useRef<((confirmed: boolean) => void) | null>(null);

Expand Down Expand Up @@ -1552,6 +1553,7 @@ export function App(): JSX.Element {
}

launchInFlightRef.current = true;
launchAbortRef.current = false;
let loadingStep: StreamLoadingStatus = "queue";
const updateLoadingStep = (next: StreamLoadingStatus): void => {
loadingStep = next;
Expand Down Expand Up @@ -1674,6 +1676,10 @@ export function App(): JSX.Element {
attempt++;
await sleep(SESSION_READY_POLL_INTERVAL_MS);

if (launchAbortRef.current) {
return;
}

const polled = await window.openNow.pollSession({
token: token || undefined,
streamingBaseUrl: newSession.streamingBaseUrl ?? effectiveStreamingBaseUrl,
Expand All @@ -1684,6 +1690,10 @@ export function App(): JSX.Element {
deviceId: newSession.deviceId,
});

if (launchAbortRef.current) {
return;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Catch block ignores abort flag, shows spurious error

Medium Severity

The catch block in handlePlayGame doesn't check launchAbortRef.current. When the user cancels during loading, handleStopStream stops the session server-side. If pollSession was already in-flight, the server may return an error for the now-stopped session, causing pollSession to throw. That exception bypasses the abort-aware return statements in the polling loop and falls into the catch block, which calls setLaunchError(...) and resetLaunchRuntime({ keepLaunchError: true }), showing a "Launch Failed" error to a user who intentionally clicked Cancel.

Additional Locations (1)
Fix in Cursor Fix in Web

setSession(polled);
setQueuePosition(polled.queuePosition);

Expand Down Expand Up @@ -1738,6 +1748,9 @@ export function App(): JSX.Element {
signalingUrl: sessionToConnect.signalingUrl,
});
} catch (error) {
if (launchAbortRef.current) {
return;
}
console.error("Launch failed:", error);
setLaunchError(toLaunchErrorState(error, loadingStep));
await window.openNow.disconnectSignaling().catch(() => {});
Expand Down Expand Up @@ -1821,6 +1834,10 @@ export function App(): JSX.Element {
const handleStopStream = useCallback(async () => {
try {
resolveExitPrompt(false);
const status = streamStatusRef.current;
if (status !== "idle" && status !== "streaming") {
launchAbortRef.current = true;
}
await window.openNow.disconnectSignaling();

const current = sessionRef.current;
Expand Down Expand Up @@ -1922,6 +1939,13 @@ export function App(): JSX.Element {

await releasePointerLockIfNeeded();

const loadingPhases: StreamStatus[] = ["queue", "setup", "starting", "connecting"];
if (loadingPhases.includes(streamStatus)) {
launchAbortRef.current = true;
await handleStopStream();
return;
}

const gameName = (streamingGame?.title || "this game").trim();
const shouldExit = await requestExitPrompt(gameName);
if (!shouldExit) {
Expand Down
3 changes: 2 additions & 1 deletion opennow-stable/src/renderer/src/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -4068,7 +4068,8 @@ button.game-card-store-chip.active:hover {
.sload {
position: fixed;
inset: 0;
z-index: 1000;
/* Above StreamView (.sv, z-index 1000) so queue/setup Cancel receives clicks */
z-index: 1100;
display: flex;
align-items: center;
justify-content: center;
Expand Down
Loading