import { FormatError } from "@/cli/error" /** * Aggregate Promise.allSettled results into a single Error that names every * failed endpoint, or return null when all fulfilled. Used at TUI bootstrap * boundaries so a single 4xx doesn't drown its parallel siblings as * unhandled rejections — every failure surfaces in one labeled message. */ export type LabeledSettled = { name: string result: PromiseSettledResult } export function aggregateFailures(labeled: LabeledSettled[]): Error | null { const failed = labeled.filter( (x): x is { name: string; result: PromiseRejectedResult } => x.result.status === "rejected", ) if (failed.length === 0) return null const reasons = Array.from( failed .map((f) => ({ name: f.name, message: reasonMessage(f.result.reason) })) .reduce((grouped, failure) => { grouped.set(failure.message, [...(grouped.get(failure.message) ?? []), failure.name]) return grouped }, new Map()) .entries(), ) .map(([message, names]) => names.length === 1 ? `${names[0]}: ${message}` : `${message}\nAffected startup requests: ${names.join(", ")}`, ) .join("; ") const summary = `${failed.length} of ${labeled.length} requests failed: ${reasons}` const err = new Error(summary) err.cause = { failures: failed.map((f) => ({ name: f.name, reason: f.result.reason })) } return err } function reasonMessage(reason: unknown): string { const formatted = FormatError(reason) if (formatted) return formatted if (reason instanceof Error) return reason.message if (typeof reason === "string") return reason if (reason && typeof reason === "object") { const obj = reason as { message?: unknown; name?: unknown } if (typeof obj.message === "string") return obj.message if (typeof obj.name === "string") return obj.name } return String(reason) }