diff --git a/app/api/compile/route.ts b/app/api/compile/route.ts index 20936d5..1c5943a 100644 --- a/app/api/compile/route.ts +++ b/app/api/compile/route.ts @@ -5,10 +5,11 @@ import { resolveAllImports, resolveAllImportsSources } from "@/lib/import-resolv import { checkRateLimit, getRateLimitReset } from "@/lib/rate-limiter"; export const runtime = "nodejs"; -export const maxDuration = 60; +export const maxDuration = 120; const MAX_BODY_SIZE = 512000; // 500KB -const WORKER_TIMEOUT_MS = 30_000; +const WORKER_TIMEOUT_EVM_MS = 30_000; +const WORKER_TIMEOUT_PVM_MS = 80_000; // resolc is slower; 20s resolver + 80s compile = 100s < 120s maxDuration interface CompileRequest { source?: string; @@ -28,8 +29,9 @@ interface CompileResponse { function compileInWorker( input: string, mode: string, - timeoutMs = WORKER_TIMEOUT_MS + timeoutMs?: number ): Promise { + const timeout = timeoutMs ?? (mode === "pvm" ? WORKER_TIMEOUT_PVM_MS : WORKER_TIMEOUT_EVM_MS); return new Promise((resolve, reject) => { const worker = new Worker(COMPILE_WORKER_CODE, { eval: true, @@ -37,8 +39,8 @@ function compileInWorker( }); const timer = setTimeout(() => { worker.terminate(); - reject(new Error("Compilation timed out after 30s")); - }, timeoutMs); + reject(new Error(`Compilation timed out after ${Math.round(timeout / 1000)}s`)); + }, timeout); worker.on("message", (msg) => { clearTimeout(timer); diff --git a/lib/compile-client.ts b/lib/compile-client.ts index 6510cb9..f1ad378 100644 --- a/lib/compile-client.ts +++ b/lib/compile-client.ts @@ -22,7 +22,24 @@ export async function compileSolidity( body: JSON.stringify({ source, mode }), }); - const data = await res.json(); + let data: any; + try { + data = await res.json(); + } catch { + // Server returned non-JSON (e.g., HTML 502/504 gateway timeout) + return { + success: false, + contracts: null, + contractNames: [], + errors: [ + { + message: `Server error (HTTP ${res.status}). PVM compilation may need more time — try again or use a simpler contract.`, + severity: "error", + }, + ], + warnings: [], + }; + } if (!res.ok) { return { @@ -91,7 +108,23 @@ export async function compileSoliditySources( body, }); - const data = await res.json(); + let data: any; + try { + data = await res.json(); + } catch { + return { + success: false, + contracts: null, + contractNames: [], + errors: [ + { + message: `Server error (HTTP ${res.status}). PVM compilation may need more time — try again or use a simpler contract.`, + severity: "error", + }, + ], + warnings: [], + }; + } if (!res.ok) { return { diff --git a/lib/import-resolver.ts b/lib/import-resolver.ts index 27e41ac..ddb3cb2 100644 --- a/lib/import-resolver.ts +++ b/lib/import-resolver.ts @@ -15,7 +15,7 @@ const PER_FETCH_TIMEOUT_MS = 10_000; const MAX_FILE_SIZE = 500_000; // 500KB per file const MAX_FILES = 50; const MAX_ITERATIONS = 10; -const TOTAL_BUDGET_MS = 30_000; +const TOTAL_BUDGET_MS = 20_000; // 20s — leaves headroom within the 120s function limit interface ResolvedSources { sources: Record;