History

Handle init failure surfacing and empty XDG_CONFIG_HOME

- Attach a rejection handler to the terminal WASM init so a load failure logs, shows a message in the viewport, and clears on retry instead of leaving a blank pane and an unhandled rejection - Treat an empty XDG_CONFIG_HOME as unset per the XDG spec instead of resolving the Ghostty config relative to the server cwd

Pixel Perfect committed 4 months ago

Commit c1caaa31 parent 7266faf2 files · +20 −5Browse files

Unified · Split

2 files
  1. apps/server/src/terminal/ghosttyStyle.ts +6 −1
  2. apps/web/src/components/ThreadTerminalDrawer.tsx +14 −4
apps/server/src/terminal/ghosttyStyle.ts+6−1
@@ -187,7 +187,12 @@ export const loadGhosttyTerminalStyle: Effect.Effect< · 186 unmodified lines
187187 const fs = yield* FileSystem.FileSystem;
188188 const path = yield* Path.Path;
189189 const home = NodeOS.homedir();
190− const xdgConfigHome = process.env["XDG_CONFIG_HOME"] ?? path.join(home, ".config");
190+ // Per the XDG spec an empty XDG_CONFIG_HOME must be treated as unset.
191+ const xdgConfigHomeEnv = process.env["XDG_CONFIG_HOME"];
192+ const xdgConfigHome =
193+ xdgConfigHomeEnv !== undefined && xdgConfigHomeEnv.length > 0
194+ ? xdgConfigHomeEnv
195+ : path.join(home, ".config");
191196
192197 const readFirstExisting = (candidates: ReadonlyArray<string>) =>
193198 Effect.gen(function* () {
apps/web/src/components/ThreadTerminalDrawer.tsx+14−4
@@ -500,6 +500,8 @@ export function TerminalViewport({ · 499 unmodified lines
500500 let teardown: (() => void) | undefined;
501501
502502 const setUpTerminal = (mount: HTMLDivElement): (() => void) => {
503+ // Clear any failure message left by an earlier init attempt.
504+ mount.textContent = "";
503505 const localApi = readLocalApi();
504506
505507 const style = readTerminalStyle();
@@ -887,10 +889,18 @@ export function TerminalViewport({ · 381 unmodified lines
887889 };
888890 };
889891
890− void ensureGhosttyReady().then(() => {
891− if (effectDisposed || containerRef.current !== mountElement) return;
892− teardown = setUpTerminal(mountElement);
893− });
892+ void ensureGhosttyReady().then(
893+ () => {
894+ if (effectDisposed || containerRef.current !== mountElement) return;
895+ teardown = setUpTerminal(mountElement);
896+ },
897+ (error: unknown) => {
898+ if (effectDisposed || containerRef.current !== mountElement) return;
899+ console.error("ghostty-web terminal failed to initialize", error);
900+ mountElement.textContent =
901+ "Terminal failed to initialize. Close and reopen the terminal to retry.";
902+ },
903+ );
894904
895905 return () => {
896906 effectDisposed = true;