Skip to content

Golf: silent failure when room no longer exists after grace period #214

@aaylward

Description

@aaylward

Problem

When a player's session expires (5-minute grace period) and all players disconnected, the room is deleted server-side. If the player returns with a permalink URL, the join attempt fails — but the only feedback is a 10-second timeout followed by a generic "Join attempt timed out" notification. There's no indication that the room no longer exists.

How errors flow today

  1. Frontend sends joinRoom with a room ID
  2. Server's handleJoinRoom finds room doesn't exist, calls sendError(client, "Room not found")
  3. Server sends {"type": "error", "message": "Room not found"}
  4. GolfNetworkPlugin.handleError (~line 203) receives it, logs it, and calls this.notify(errorMessage, context)
  5. notify calls onNotification callback → hook's showNotification → sets a temporary notification string
  6. The notification appears briefly but the permalink join timeout is still running
  7. After 10 seconds, the timeout fires and shows "Join attempt timed out"

The error from the server arrives almost immediately but is treated as a generic notification — the permalink join flow doesn't know the join already failed.

Expected behavior

If a room/game no longer exists, the user should see a clear "This room no longer exists" message within ~1 second and be offered a "Create New Room" action, not wait 10 seconds for a timeout.

Suggested approach

  1. Add an onError callback to the adapter's callback interface (networkAdapter.ts:107-115) separate from onNotification, so the hook can distinguish errors from informational messages.

  2. In the plugin's handleError (golfNetworkPlugin.ts:203-217), call the error callback with the raw message so the hook can inspect it.

  3. In the hook (useGolfGame.ts), add an error handler that checks if a permalink join is in progress and the error matches room/game-not-found:

    onError: (errorMessage: string) => {
      if (permalinkJoinAttempt.isAttempting && 
          (errorMessage.includes('Room not found') || errorMessage.includes('Game not found'))) {
        clearTimeout(permalinkTimeoutRef.current)
        setPermalinkJoinAttempt({
          isAttempting: false,
          roomId: null, gameId: null,
          error: 'This room no longer exists.',
          gameJoinAttempted: false
        })
      }
    }
  4. In the UI (GolfGame.tsx), when permalinkJoinAttempt.error is set and the user isn't in a room, show the error with a "Create New Room" button instead of the loading state.

Files

  • src/plugins/golfNetworkPlugin.ts:203-217 (handleError)
  • src/utils/networkAdapter.ts:107-115 (callback interface)
  • src/hooks/useGolfGame.ts:606-615 (timeout handler, new error handler)
  • src/apps/golf/components/GolfGame.tsx (error display in lobby/loading state)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions