Files
tutti/packages/agent/gui/test/reactRenderLoopConsoleTrap.ts
agent-radar 2ed3415fb7
Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
2026-09-01 20:17:27 +08:00

50 lines
1.1 KiB
TypeScript

type ConsoleLike = {
error: (...args: unknown[]) => void;
};
const reactRenderLoopErrorPattern =
/maximum update depth exceeded|too many re-renders|react limits the number of renders|react limits the number of nested updates/iu;
export function installReactRenderLoopConsoleTrap({
console: targetConsole
}: {
console: ConsoleLike;
}): () => void {
const originalError = targetConsole.error;
targetConsole.error = (...args: unknown[]) => {
originalError(...args);
const message = args.map(formatConsoleArg).join(" ");
if (!reactRenderLoopErrorPattern.test(message)) {
return;
}
throw new Error(
[
"React render loop detected from console.error.",
"The original React diagnostic was:",
message
].join("\n")
);
};
return () => {
targetConsole.error = originalError;
};
}
function formatConsoleArg(arg: unknown): string {
if (arg instanceof Error) {
return `${arg.name}: ${arg.message}\n${arg.stack ?? ""}`;
}
if (typeof arg === "string") {
return arg;
}
try {
return JSON.stringify(arg);
} catch {
return String(arg);
}
}