From f2c644fad01db190107ac1e4d072e20eb363f92e Mon Sep 17 00:00:00 2001 From: Aryan Bhati Date: Tue, 19 May 2026 18:11:45 +0530 Subject: [PATCH] fix: improve large repository ingest stability and timeout handling --- backend/core/ingest/git_ingest.py | 4 ++-- .../src/components/ingest/GitHubInput.tsx | 23 +++++++++++-------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/backend/core/ingest/git_ingest.py b/backend/core/ingest/git_ingest.py index bf00ffa..3ce6199 100644 --- a/backend/core/ingest/git_ingest.py +++ b/backend/core/ingest/git_ingest.py @@ -74,11 +74,11 @@ def _do_clone_sync(url: str, repo_dir: Path, depth: int = 1) -> None: cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, - timeout=120, + timeout=1800, ) except subprocess.TimeoutExpired: raise GitIngestError( - f"Git clone timed out after 120 s for {url}. " + f"Git clone timed out after 1800 s for {url}. " "Try a smaller or less active repository.", error_code="CLONE_TIMEOUT", ) diff --git a/frontend/src/components/ingest/GitHubInput.tsx b/frontend/src/components/ingest/GitHubInput.tsx index 35cd5e3..8a60c00 100644 --- a/frontend/src/components/ingest/GitHubInput.tsx +++ b/frontend/src/components/ingest/GitHubInput.tsx @@ -5,7 +5,7 @@ import { ingestGitHub } from "../../api/ingest"; import { useSessionStore } from "../../store/sessionStore"; import { useUiStore } from "../../store/uiStore"; -const CLONE_TIMEOUT_MS = 120_000; +const CLONE_TIMEOUT_MS = 600_000; export function GitHubInput() { const [url, setUrl] = useState(""); @@ -28,18 +28,20 @@ export function GitHubInput() { setError(null); setSessionError(null); - const controller = new AbortController(); - const timeoutId = setTimeout(() => controller.abort(), CLONE_TIMEOUT_MS); - try { - const data = await ingestGitHub(url.trim(), controller.signal); - clearTimeout(timeoutId); + const data = await ingestGitHub(url.trim()); setSessionAndLoading(data); setShowIngestModal(false); } catch (err: unknown) { - clearTimeout(timeoutId); setIsLoading(false); - + if ( + err instanceof Error && + (err.message.toLowerCase() === "canceled" || + err.message.toLowerCase() === "cancelled") + ) { + setError("Clone operation was cancelled or timed out."); + return; + } // AbortError from our 120s timeout if (err instanceof DOMException && err.name === "AbortError") { setError("Clone timed out. The repository might be too large or the network is slow."); @@ -65,7 +67,10 @@ export function GitHubInput() { } else { setError(`Server error (${status ?? "unknown"}). Please try again.`); } - } else if (err && typeof err === "object" && "request" in err) { + } else if (err && + typeof err === "object" && + "request" in err && + !(err instanceof DOMException)) { setError("Cannot reach the server. Is the backend running on port 8000?"); } else if (