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
50 lines
1.1 KiB
TypeScript
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);
|
|
}
|
|
}
|