Skip to content

Stop reconnecting after backend disconnects - #13302

Merged
pierremtb merged 3 commits into
mainfrom
pierremtb/issue-13161-terminal-engine-errors
Sep 10, 2026
Merged

Stop reconnecting after backend disconnects#13302
pierremtb merged 3 commits into
mainfrom
pierremtb/issue-13161-terminal-engine-errors

Conversation

@pierremtb

@pierremtb pierremtb commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Closes #13163.

What

  • classify only the current legacy backend-disconnect response as a terminal engine connection error
  • tear down that connection immediately and route the terminal error through the existing websocket-close path
  • stop both established auto-reconnect and the initial connection retry loop
  • show manual reconnect UI instead of retrying indefinitely
  • keep all other legacy failures on their existing paths, including the common pre-header auth_token_missing response

Why

This is intentionally the smallest deployable compatibility change for today's untyped backend-disconnect response. It introduces the shared terminal-error plumbing but no broader error taxonomy or new API response types. #13328 is stacked on this PR and replaces the legacy message match with the typed protocol.

How to test

  1. Open the Vercel preview and open a project until the engine stream is working.
  2. Open DevTools → Network
  3. In DevTools → Console, run:
const ws = window.engineCommandManager.connection?.websocket

if (!ws || ws.readyState !== WebSocket.OPEN) {
  throw new Error("Engine WebSocket is not open")
}

ws.dispatchEvent(
  new MessageEvent("message", {
    data: JSON.stringify({
      success: false,
      request_id: "manual-backend-disconnect-test",
      errors: [
        {
          error_code: "internal_api",
          message:
            "modeling connection interrupted; please reconnect and retry",
        },
      ],
    }),
  })
)

Expected behavior:

  • The stream disconnects immediately.
  • The “Failed to connect” screen appears with a Reconnect button.
  • No new engine WebSocket is created automatically.

@pierremtb
pierremtb requested a review from a team as a code owner August 25, 2026 12:36
@vercel

vercel Bot commented Aug 25, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
modeling-app Ready Ready Preview Sep 9, 2026 12:28pm UTC

Request Review

@pierremtb
pierremtb marked this pull request as draft August 25, 2026 12:41
@pierremtb
pierremtb force-pushed the pierremtb/issue-13161-terminal-engine-errors branch from fac6dcc to 4e5d7f1 Compare September 7, 2026 15:40
@pierremtb
pierremtb force-pushed the pierremtb/issue-13161-terminal-engine-errors branch from 742e136 to 7ab0897 Compare September 7, 2026 20:21
@pierremtb pierremtb changed the title Stop reconnecting on terminal engine errors Stop reconnecting after backend disconnects Sep 7, 2026
@pierremtb
pierremtb force-pushed the pierremtb/issue-13161-terminal-engine-errors branch from 7ab0897 to 125f5c5 Compare September 7, 2026 20:29
Comment on lines +147 to +152
const connectionError: EngineConnectionError = {
kind: EngineConnectionErrorKind.BackendDisconnect,
message: backendDisconnectError.message,
terminal: true,
}
tearDownManager({ websocketClosed: true, connectionError })

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This is where we reuse the detection introduced for client error reporting to prevent further reconnect attempts.

Comment on lines +341 to +355
export enum EngineConnectionErrorKind {
BackendDisconnect = 'backend-disconnect',
}

export type EngineConnectionError = {
kind: EngineConnectionErrorKind
message: string
terminal: boolean
}

export type EngineDisconnectEventDetail = {
code?: string
connectionError?: EngineConnectionError
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I have upcoming work at #13328, https://github.com/KittyCAD/api/pull/4472, and KittyCAD/modeling-api#1340 to get proper error types and use that instead of the string parsing.

@pierremtb
pierremtb marked this pull request as ready for review September 7, 2026 21:09
@pierremtb
pierremtb enabled auto-merge (squash) September 7, 2026 21:13
@andrewvarga

Copy link
Copy Markdown
Contributor

A small edge case I haven't reproduced: the idle callback still seems to be activated when the backend disconnects, so this can happen:

  • backend disconnects due to an error
  • idle timeout completes after 1 minute
  • move your mouse -> new connection is started

I'm thinking if we're on the disconnection page, the idle state shouldn't be triggered ideally, but a simpler fix is to guard all automatic reconnections with something like:

if (engineCommandManager.lastConnectionError?.terminal) return

It doesn't feel like a big issue though.

@andrewvarga

Copy link
Copy Markdown
Contributor

Confirmed my finding is fixed!

@pierremtb
pierremtb merged commit e3f4f68 into main Sep 10, 2026
59 of 60 checks passed
@pierremtb
pierremtb deleted the pierremtb/issue-13161-terminal-engine-errors branch September 10, 2026 10:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bound ZDS retries after an Engine disconnects

2 participants