When implementing networked features (hub dispatch, reconnect/reattach, model/catalog fetches, and local-proxy HTTP), ensure retries are safe and bounded:
connecting, prefer bounded wait + retry for reads (e.g., transcript/status) instead of failing immediately.fetch/socket call as a fallback path; propagate the same abort logic.0.0.0.0, IPv4-mapped loopback).Example pattern (safe resend + bounded, abortable requests):
async function sendWithSafeRetry(params: {
attemptId: string;
sessionId: string;
send: () => Promise<{ dispatched: boolean; error?: { code?: string } }>;
onProgress: (msg: string) => void;
abortSignal: AbortSignal;
timeoutMs: number;
}) {
const { send, timeoutMs, abortSignal } = params;
const controller = new AbortController();
const t = setTimeout(() => controller.abort(), timeoutMs);
abortSignal.addEventListener("abort", () => controller.abort(), { once: true });
try {
params.onProgress("sending");
const { dispatched, error } = await send();
if (!dispatched) {
// Safe to retry / re-offer draft only for pre-dispatch failures.
// If you retry here, ensure you don’t exceed UX expectations.
if (error?.code === "transport_error") {
params.onProgress("retrying");
return await send();
}
}
return { dispatched, error };
} finally {
clearTimeout(t);
}
}
Use the same principles for: