Improve connection selection and agent hydration reliability

This commit is contained in:
Mohamed Boudra
2026-02-14 11:31:57 +07:00
parent 21f191583f
commit c4bebb97ab
11 changed files with 523 additions and 59 deletions
@@ -104,9 +104,11 @@ export function createEncryptedTransport(
onerror: (error) => emitError(error),
});
} catch (error) {
logger.warn({ err: error }, "relay_e2ee_handshake_failed");
logger.warn({ err: normalizeTransportError(error) }, "relay_e2ee_handshake_failed");
emitError(error);
base.close(1011, "E2EE handshake failed");
// Browser WebSocket.close only accepts 1000 or 3000-4999.
// Use an app-defined code so this path works in browser and Node runtimes.
base.close(4001, "E2EE handshake failed");
}
};
@@ -189,3 +191,14 @@ function invokeHandler<TArgs extends unknown[]>(
// no-op
}
}
function normalizeTransportError(error: unknown): Record<string, string> {
if (error instanceof Error) {
return {
name: error.name,
message: error.message,
...(typeof error.stack === "string" ? { stack: error.stack } : {}),
};
}
return { message: String(error) };
}
@@ -1,5 +1,6 @@
import { describe, expect, test, vi } from "vitest";
import {
createEncryptedTransport,
createWebSocketTransportFactory,
decodeMessageData,
describeTransportClose,
@@ -8,7 +9,48 @@ import {
extractRelayMessageData,
} from "./daemon-client-transport.js";
const createClientChannelMock = vi.hoisted(() => vi.fn());
vi.mock("@getpaseo/relay/e2ee", () => ({
createClientChannel: createClientChannelMock,
}));
describe("daemon-client transport helpers", () => {
test("createEncryptedTransport closes handshake failures with browser-safe code", async () => {
createClientChannelMock.mockReset();
createClientChannelMock.mockRejectedValueOnce(new Error("handshake failed"));
let openHandler: (() => void) | null = null;
const close = vi.fn();
createEncryptedTransport(
{
send: vi.fn(),
close,
onOpen: (handler) => {
openHandler = handler;
return () => {
if (openHandler === handler) {
openHandler = null;
}
};
},
onClose: () => () => {},
onError: () => () => {},
onMessage: () => () => {},
},
"daemon-public-key",
{ warn: vi.fn() }
);
expect(openHandler).not.toBeNull();
openHandler?.();
await vi.waitFor(() => {
expect(close).toHaveBeenCalledWith(4001, "E2EE handshake failed");
});
});
test("createWebSocketTransportFactory forwards sends when socket is open", () => {
const addEventListener = vi.fn();
const removeEventListener = vi.fn();