fix(hub): return relationship command errors

This commit is contained in:
Mohamed Boudra
2026-07-13 16:46:24 +02:00
parent b653719281
commit 7371fff578
2 changed files with 89 additions and 16 deletions
@@ -10,6 +10,7 @@ import {
} from "./daemon-session.js";
import type { DaemonWebSocketRuntimeDiagnosticSnapshot } from "./diagnostics.js";
import type { ProviderAvailability } from "../../agent/agent-manager.js";
import type { HubRelationshipManagement } from "../../hub/relationship-controller.js";
import type { SessionOutboundMessage } from "../../messages.js";
const tempDirs: string[] = [];
@@ -40,6 +41,7 @@ function makeSubsystem(overrides: {
daemonRuntimeConfig?: DaemonRuntimeConfig;
listProviderAvailability?: () => Promise<ProviderAvailability[]>;
getWebSocketRuntimeMetrics?: () => DaemonWebSocketRuntimeDiagnosticSnapshot | null;
hubRelationships?: HubRelationshipManagement;
}) {
const emitted: SessionOutboundMessage[] = [];
const restartIntents: Parameters<DaemonSessionHost["emitLifecycleIntent"]>[0][] = [];
@@ -60,12 +62,67 @@ function makeSubsystem(overrides: {
listWorkspaces: async () => [],
listProviderAvailability: overrides.listProviderAvailability ?? (async () => []),
getWebSocketRuntimeMetrics: overrides.getWebSocketRuntimeMetrics,
hubRelationships: overrides.hubRelationships,
logger: pino({ level: "silent" }),
});
return { subsystem, emitted, paseoHome, restartIntents };
}
describe("DaemonSession", () => {
test("Hub relationship command failures return correlated RPC errors", async () => {
const { subsystem, emitted } = makeSubsystem({
hubRelationships: {
connect: async () => {
throw new Error("Hub rejected enrollment (401)");
},
status: () => ({
state: "not_connected",
relationshipId: null,
hubOrigin: null,
scopes: [],
connectedAt: null,
lastError: null,
}),
disconnect: async () => {
throw new Error("Hub revocation failed (503)");
},
},
});
await subsystem.handleHubRelationshipRequest({
type: "hub.relationship.connect.request",
requestId: "connect-1",
hubUrl: "https://hub.test",
token: "token",
});
await subsystem.handleHubRelationshipRequest({
type: "hub.relationship.disconnect.request",
requestId: "disconnect-1",
force: false,
});
expect(emitted).toEqual([
{
type: "rpc_error",
payload: {
requestId: "connect-1",
requestType: "hub.relationship.connect.request",
error: "Hub rejected enrollment (401)",
code: "handler_error",
},
},
{
type: "rpc_error",
payload: {
requestId: "disconnect-1",
requestType: "hub.relationship.disconnect.request",
error: "Hub revocation failed (503)",
code: "handler_error",
},
},
]);
});
test("status reports identity, runtime config, and providers with errors normalized to null", async () => {
const { subsystem, emitted } = makeSubsystem({
serverId: "srv-1",
@@ -107,27 +107,43 @@ export class DaemonSession {
}
>,
): Promise<void> {
if (!this.hubRelationships) throw new Error("Hub relationship management is unavailable");
if (msg.type === "hub.relationship.connect.request") {
const status = await this.hubRelationships.connect({ hubUrl: msg.hubUrl, token: msg.token });
try {
if (!this.hubRelationships) throw new Error("Hub relationship management is unavailable");
if (msg.type === "hub.relationship.connect.request") {
const status = await this.hubRelationships.connect({
hubUrl: msg.hubUrl,
token: msg.token,
});
this.host.emit({
type: "hub.relationship.connect.response",
payload: { requestId: msg.requestId, status },
});
return;
}
if (msg.type === "hub.relationship.disconnect.request") {
const result = await this.hubRelationships.disconnect({ force: msg.force ?? false });
this.host.emit({
type: "hub.relationship.disconnect.response",
payload: { requestId: msg.requestId, ...result },
});
return;
}
this.host.emit({
type: "hub.relationship.connect.response",
payload: { requestId: msg.requestId, status },
type: "hub.relationship.get_status.response",
payload: { requestId: msg.requestId, status: this.hubRelationships.status() },
});
return;
}
if (msg.type === "hub.relationship.disconnect.request") {
const result = await this.hubRelationships.disconnect({ force: msg.force ?? false });
} catch (error) {
this.logger.error({ err: error }, "Failed to handle Hub relationship request");
this.host.emit({
type: "hub.relationship.disconnect.response",
payload: { requestId: msg.requestId, ...result },
type: "rpc_error",
payload: {
requestId: msg.requestId,
requestType: msg.type,
error: error instanceof Error ? error.message : String(error),
code: "handler_error",
},
});
return;
}
this.host.emit({
type: "hub.relationship.get_status.response",
payload: { requestId: msg.requestId, status: this.hubRelationships.status() },
});
}
async handleGetStatusRequest(