refactor(gateway): share node invoke error handling
This commit is contained in:
@@ -10,7 +10,7 @@ import { createBrowserRouteDispatcher } from "../../browser/routes/dispatcher.js
|
||||
import { loadConfig } from "../../config/config.js";
|
||||
import { isNodeCommandAllowed, resolveNodeCommandAllowlist } from "../node-command-policy.js";
|
||||
import { ErrorCodes, errorShape } from "../protocol/index.js";
|
||||
import { safeParseJson } from "./nodes.helpers.js";
|
||||
import { respondUnavailableOnNodeInvokeError, safeParseJson } from "./nodes.helpers.js";
|
||||
|
||||
type BrowserRequestParams = {
|
||||
method?: string;
|
||||
@@ -194,14 +194,7 @@ export const browserHandlers: GatewayRequestHandlers = {
|
||||
timeoutMs,
|
||||
idempotencyKey: crypto.randomUUID(),
|
||||
});
|
||||
if (!res.ok) {
|
||||
respond(
|
||||
false,
|
||||
undefined,
|
||||
errorShape(ErrorCodes.UNAVAILABLE, res.error?.message ?? "node invoke failed", {
|
||||
details: { nodeError: res.error ?? null },
|
||||
}),
|
||||
);
|
||||
if (!respondUnavailableOnNodeInvokeError(respond, res)) {
|
||||
return;
|
||||
}
|
||||
const payload = res.payloadJSON ? safeParseJson(res.payloadJSON) : res.payload;
|
||||
|
||||
@@ -17,7 +17,11 @@ import {
|
||||
validateExecApprovalsSetParams,
|
||||
} from "../protocol/index.js";
|
||||
import { resolveBaseHashParam } from "./base-hash.js";
|
||||
import { respondUnavailableOnThrow, safeParseJson } from "./nodes.helpers.js";
|
||||
import {
|
||||
respondUnavailableOnNodeInvokeError,
|
||||
respondUnavailableOnThrow,
|
||||
safeParseJson,
|
||||
} from "./nodes.helpers.js";
|
||||
import { assertValidParams } from "./validation.js";
|
||||
|
||||
function requireApprovalsBaseHash(
|
||||
@@ -147,14 +151,7 @@ export const execApprovalsHandlers: GatewayRequestHandlers = {
|
||||
command: "system.execApprovals.get",
|
||||
params: {},
|
||||
});
|
||||
if (!res.ok) {
|
||||
respond(
|
||||
false,
|
||||
undefined,
|
||||
errorShape(ErrorCodes.UNAVAILABLE, res.error?.message ?? "node invoke failed", {
|
||||
details: { nodeError: res.error ?? null },
|
||||
}),
|
||||
);
|
||||
if (!respondUnavailableOnNodeInvokeError(respond, res)) {
|
||||
return;
|
||||
}
|
||||
const payload = res.payloadJSON ? safeParseJson(res.payloadJSON) : res.payload;
|
||||
@@ -188,14 +185,7 @@ export const execApprovalsHandlers: GatewayRequestHandlers = {
|
||||
command: "system.execApprovals.set",
|
||||
params: { file, baseHash },
|
||||
});
|
||||
if (!res.ok) {
|
||||
respond(
|
||||
false,
|
||||
undefined,
|
||||
errorShape(ErrorCodes.UNAVAILABLE, res.error?.message ?? "node invoke failed", {
|
||||
details: { nodeError: res.error ?? null },
|
||||
}),
|
||||
);
|
||||
if (!respondUnavailableOnNodeInvokeError(respond, res)) {
|
||||
return;
|
||||
}
|
||||
const payload = safeParseJson(res.payloadJSON ?? null);
|
||||
|
||||
@@ -51,3 +51,28 @@ export function safeParseJson(value: string | null | undefined): unknown {
|
||||
return { payloadJSON: value };
|
||||
}
|
||||
}
|
||||
|
||||
export function respondUnavailableOnNodeInvokeError<T extends { ok: boolean; error?: unknown }>(
|
||||
respond: RespondFn,
|
||||
res: T,
|
||||
): res is T & { ok: true } {
|
||||
if (res.ok) {
|
||||
return true;
|
||||
}
|
||||
const message =
|
||||
res.error && typeof res.error === "object" && "message" in res.error
|
||||
? (res.error as { message?: unknown }).message
|
||||
: null;
|
||||
respond(
|
||||
false,
|
||||
undefined,
|
||||
errorShape(
|
||||
ErrorCodes.UNAVAILABLE,
|
||||
typeof message === "string" ? message : "node invoke failed",
|
||||
{
|
||||
details: { nodeError: res.error ?? null },
|
||||
},
|
||||
),
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import {
|
||||
import { handleNodeInvokeResult } from "./nodes.handlers.invoke-result.js";
|
||||
import {
|
||||
respondInvalidParams,
|
||||
respondUnavailableOnNodeInvokeError,
|
||||
respondUnavailableOnThrow,
|
||||
safeParseJson,
|
||||
uniqueSortedStrings,
|
||||
@@ -433,14 +434,7 @@ export const nodeHandlers: GatewayRequestHandlers = {
|
||||
timeoutMs: p.timeoutMs,
|
||||
idempotencyKey: p.idempotencyKey,
|
||||
});
|
||||
if (!res.ok) {
|
||||
respond(
|
||||
false,
|
||||
undefined,
|
||||
errorShape(ErrorCodes.UNAVAILABLE, res.error?.message ?? "node invoke failed", {
|
||||
details: { nodeError: res.error ?? null },
|
||||
}),
|
||||
);
|
||||
if (!respondUnavailableOnNodeInvokeError(respond, res)) {
|
||||
return;
|
||||
}
|
||||
const payload = res.payloadJSON ? safeParseJson(res.payloadJSON) : res.payload;
|
||||
|
||||
Reference in New Issue
Block a user