@@ -6,8 +6,12 @@ import { supabase } from "../../lib/supabaseClient";
66const API_BASE = process . env . NEXT_PUBLIC_API_URL || "https://edeziav2.onrender.com/api/v1" ;
77
88const safeFetch = async ( url : string , options : RequestInit = { } ) : Promise < Response > => {
9+ const isHeavyRequest = url . includes ( "/upload" ) || url . includes ( "/submissions" ) || url . includes ( "/runs" ) || url . includes ( "/grade" ) ;
10+ const defaultTimeout = isHeavyRequest ? 120000 : 8000 ; // 120 seconds for AI/upload tasks, 8 seconds for fast auth
11+ const timeoutMs = ( options as any ) . timeout !== undefined ? ( options as any ) . timeout : defaultTimeout ;
12+
913 const controller = new AbortController ( ) ;
10- const id = setTimeout ( ( ) => controller . abort ( ) , 6000 ) ; // 6 seconds timeout
14+ const id = timeoutMs > 0 ? setTimeout ( ( ) => controller . abort ( ) , timeoutMs ) : null ;
1115
1216 const fetchOptions = {
1317 ...options ,
@@ -21,7 +25,7 @@ const safeFetch = async (url: string, options: RequestInit = {}): Promise<Respon
2125 const rest = parts . slice ( 1 ) . join ( "," ) ;
2226
2327 // Resolve path from secondary base dynamically
24- const secondBase = "https://edeziav2.onrender.com/api/v1" ;
28+ const secondBase = "https://edeziav2.onrender.com/api/v1" ;
2529 let path = "" ;
2630 if ( rest . startsWith ( secondBase ) ) {
2731 path = rest . substring ( secondBase . length ) ;
@@ -37,29 +41,29 @@ const safeFetch = async (url: string, options: RequestInit = {}): Promise<Respon
3741
3842 try {
3943 const res = await fetch ( url1 , fetchOptions ) ;
40- clearTimeout ( id ) ;
44+ if ( id ) clearTimeout ( id ) ;
4145 return res ;
4246 } catch ( err ) {
4347 console . warn ( `Local API offline at ${ url1 } , falling back to remote production at ${ url2 } ` , err ) ;
4448
4549 // Reset timeout for fallback fetch
4650 const fallbackController = new AbortController ( ) ;
47- const fallbackId = setTimeout ( ( ) => fallbackController . abort ( ) , 6000 ) ;
51+ const fallbackId = timeoutMs > 0 ? setTimeout ( ( ) => fallbackController . abort ( ) , timeoutMs ) : null ;
4852 try {
4953 const res = await fetch ( url2 , { ...options , signal : fallbackController . signal } ) ;
50- clearTimeout ( fallbackId ) ;
54+ if ( fallbackId ) clearTimeout ( fallbackId ) ;
5155 return res ;
5256 } catch ( fallbackErr ) {
53- clearTimeout ( fallbackId ) ;
57+ if ( fallbackId ) clearTimeout ( fallbackId ) ;
5458 throw fallbackErr ;
5559 }
5660 }
5761 }
5862 const res = await fetch ( url , fetchOptions ) ;
59- clearTimeout ( id ) ;
63+ if ( id ) clearTimeout ( id ) ;
6064 return res ;
6165 } catch ( error ) {
62- clearTimeout ( id ) ;
66+ if ( id ) clearTimeout ( id ) ;
6367 throw error ;
6468 }
6569} ;
0 commit comments