huskies: merge 949
This commit is contained in:
+62
-28
@@ -56,7 +56,7 @@ const RETRY_DELAY_MS = 250;
|
||||
*/
|
||||
function rpcAttempt<T>(
|
||||
method: string,
|
||||
params: Record<string, unknown>,
|
||||
params: object,
|
||||
timeoutMs: number,
|
||||
): Promise<T> {
|
||||
return new Promise<T>((resolve, reject) => {
|
||||
@@ -102,34 +102,68 @@ function rpcAttempt<T>(
|
||||
};
|
||||
|
||||
ws.onmessage = (event) => {
|
||||
let data: unknown;
|
||||
try {
|
||||
const data = JSON.parse(event.data);
|
||||
if (
|
||||
data.kind === "rpc_response" &&
|
||||
data.correlation_id === correlationId
|
||||
) {
|
||||
settled = true;
|
||||
clearTimeout(timer);
|
||||
try {
|
||||
ws.close();
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
if (data.ok) {
|
||||
resolve(data.result as T);
|
||||
} else {
|
||||
reject(
|
||||
new RpcError(
|
||||
data.error || `RPC error: ${data.code || "UNKNOWN"}`,
|
||||
data.code,
|
||||
method,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
// Ignore other frames (pipeline_state, onboarding_status, etc.)
|
||||
data = JSON.parse(event.data);
|
||||
} catch {
|
||||
/* ignore non-JSON / malformed frames */
|
||||
// Non-JSON frame is not ours — keep waiting.
|
||||
return;
|
||||
}
|
||||
if (!data || typeof data !== "object") {
|
||||
return;
|
||||
}
|
||||
const frame = data as {
|
||||
kind?: unknown;
|
||||
correlation_id?: unknown;
|
||||
ok?: unknown;
|
||||
result?: unknown;
|
||||
error?: unknown;
|
||||
code?: unknown;
|
||||
};
|
||||
if (frame.kind !== "rpc_response" || frame.correlation_id !== correlationId) {
|
||||
// Not addressed to this call — ignore (pipeline_state, etc.).
|
||||
return;
|
||||
}
|
||||
settled = true;
|
||||
clearTimeout(timer);
|
||||
try {
|
||||
ws.close();
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
if (typeof frame.ok !== "boolean") {
|
||||
reject(
|
||||
new RpcError(
|
||||
`Malformed RPC response for ${method}: missing or non-boolean 'ok' field`,
|
||||
"MALFORMED",
|
||||
method,
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (frame.ok) {
|
||||
if (!("result" in frame)) {
|
||||
reject(
|
||||
new RpcError(
|
||||
`Malformed RPC response for ${method}: 'ok:true' frame missing 'result' field`,
|
||||
"MALFORMED",
|
||||
method,
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
resolve(frame.result as T);
|
||||
} else {
|
||||
const errMsg =
|
||||
typeof frame.error === "string" ? frame.error : undefined;
|
||||
const errCode = typeof frame.code === "string" ? frame.code : undefined;
|
||||
reject(
|
||||
new RpcError(
|
||||
errMsg || `RPC error: ${errCode || "UNKNOWN"}`,
|
||||
errCode,
|
||||
method,
|
||||
),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -183,7 +217,7 @@ function sleep(ms: number): Promise<void> {
|
||||
*/
|
||||
export async function rpcCall<T = unknown>(
|
||||
method: string,
|
||||
params: Record<string, unknown> = {},
|
||||
params: object = {},
|
||||
timeoutMs = 5000,
|
||||
): Promise<T> {
|
||||
let lastErr: unknown;
|
||||
|
||||
Reference in New Issue
Block a user