History

Clarify SSH IPC error presentation

Julius Marminge committed 4 months ago

Commit 477a96f1 parent 19550842 files · +20 −5Browse files

Unified · Split

2 files
  1. apps/desktop/src/ipc/methods/sshEnvironment.test.ts +14 −2
  2. apps/desktop/src/ipc/methods/sshEnvironment.ts +6 −3
apps/desktop/src/ipc/methods/sshEnvironment.test.ts+14−2
@@ -5,6 +5,7 @@ import { · 4 unmodified lines
55 } from "@t3tools/contracts";
66 import {
77 SshCommandSpawnError,
8+ SshCommandTimeoutError,
89 SshHttpBridgeError,
910 SshPasswordPromptError,
1011 } from "@t3tools/ssh/errors";
@@ -22,7 +23,7 @@ import { · 11 unmodified lines
2223 DesktopSshEnvironmentRequestError,
2324 ensureSshEnvironment,
2425 fetchSshEnvironmentDescriptor,
25− toDesktopSshOperationPresentationError,
26+ toDesktopSshIpcPresentationError,
2627 } from "./sshEnvironment.ts";
2728 import * as DesktopSshEnvironment from "../../ssh/DesktopSshEnvironment.ts";
2829 import * as DesktopSshPasswordPrompts from "../../ssh/DesktopSshPasswordPrompts.ts";
@@ -102,12 +103,23 @@ describe("SSH environment IPC", () => { · 73 unmodified lines
102103 cause,
103104 });
104105
105− const presentation = toDesktopSshOperationPresentationError(structured);
106+ const presentation = toDesktopSshIpcPresentationError(structured);
106107 assert.equal(structured.message, "Failed to spawn SSH command for devbox.");
107108 assert.equal(presentation.message, cause.message);
108109 assert.strictEqual(presentation.cause, structured);
109110 });
110111
112+ it("passes structural SSH errors without process causes through the IPC boundary", () => {
113+ const structured = new SshCommandTimeoutError({
114+ command: "ssh",
115+ argumentCount: 0,
116+ target: "devbox",
117+ timeoutMs: 30_000,
118+ });
119+
120+ assert.strictEqual(toDesktopSshIpcPresentationError(structured), structured);
121+ });
122+
111123 it.effect("fetches and decodes the remote environment descriptor", () => {
112124 const requestUrls: string[] = [];
113125 const layer = makeHttpClientLayer((request) =>
apps/desktop/src/ipc/methods/sshEnvironment.ts+6−3
@@ -73,7 +73,10 @@ const isSshCausePresentationError = Schema.is( · 72 unmodified lines
7373 ]),
7474 );
7575
76−export function toDesktopSshOperationPresentationError(
76+// Electron only forwards the message from a rejected ipcRenderer.invoke promise. Keep the typed,
77+// structural SSH error intact as the cause for main-process diagnostics while preserving the
78+// actionable process message that the renderer historically presented to the user.
79+export function toDesktopSshIpcPresentationError(
7780 error: DesktopSshEnvironment.DesktopSshEnvironmentOperationError,
7881 ): DesktopSshEnvironment.DesktopSshEnvironmentOperationError | Error {
7982 if (isSshCausePresentationError(error) && error.cause instanceof Error) {
@@ -169,7 +172,7 @@ export const ensureSshEnvironment = DesktopIpc.makeIpcMethod({ · 89 unmodified lines
169172 )
170173 : Effect.fail(error),
171174 }),
172− Effect.mapError(toDesktopSshOperationPresentationError),
175+ Effect.mapError(toDesktopSshIpcPresentationError),
173176 );
174177 }),
175178 });
@@ -182,7 +185,7 @@ export const disconnectSshEnvironment = DesktopIpc.makeIpcMethod({ · 6 unmodified lines
182185 const sshEnvironment = yield* DesktopSshEnvironment.DesktopSshEnvironment;
183186 yield* sshEnvironment
184187 .disconnectEnvironment(target)
185− .pipe(Effect.mapError(toDesktopSshOperationPresentationError));
188+ .pipe(Effect.mapError(toDesktopSshIpcPresentationError));
186189 }),
187190 });
188191