- 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
Unified · Split
| @@ -187,7 +187,12 @@ export const loadGhosttyTerminalStyle: Effect.Effect< · 186 unmodified lines | ||
| 187 | 187 | const fs = yield* FileSystem.FileSystem; |
| 188 | 188 | const path = yield* Path.Path; |
| 189 | 189 | 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"); | |
| 191 | 196 | |
| 192 | 197 | const readFirstExisting = (candidates: ReadonlyArray<string>) => |
| 193 | 198 | Effect.gen(function* () { |
| @@ -500,6 +500,8 @@ export function TerminalViewport({ · 499 unmodified lines | ||
| 500 | 500 | let teardown: (() => void) | undefined; |
| 501 | 501 | |
| 502 | 502 | const setUpTerminal = (mount: HTMLDivElement): (() => void) => { |
| 503 | + // Clear any failure message left by an earlier init attempt. | |
| 504 | + mount.textContent = ""; | |
| 503 | 505 | const localApi = readLocalApi(); |
| 504 | 506 | |
| 505 | 507 | const style = readTerminalStyle(); |
| @@ -887,10 +889,18 @@ export function TerminalViewport({ · 381 unmodified lines | ||
| 887 | 889 | }; |
| 888 | 890 | }; |
| 889 | 891 | |
| 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 | + ); | |
| 894 | 904 | |
| 895 | 905 | return () => { |
| 896 | 906 | effectDisposed = true; |