/** * Timeout handling utilities */ import * as plugins from '../webrequest.plugins.js'; /** * Create an AbortController with timeout */ export function createTimeoutController(timeoutMs: number): { controller: AbortController; cleanup: () => void; } { const controller = new AbortController(); let timeoutId: any; // Set up timeout plugins.smartdelay .delayFor(timeoutMs) .then(() => { controller.abort(); }) .then((result) => { timeoutId = result; }); // Cleanup function to clear timeout const cleanup = () => { if (timeoutId !== undefined) { // smartdelay doesn't expose a cancel method, so we just ensure // the controller won't abort if already completed } }; return { controller, cleanup }; } /** * Execute a fetch with timeout */ export async function fetchWithTimeout( url: string, init: RequestInit, timeoutMs: number, ): Promise { const { controller, cleanup } = createTimeoutController(timeoutMs); try { const response = await fetch(url, { ...init, signal: controller.signal, }); cleanup(); return response; } catch (error) { cleanup(); // Re-throw with more informative error if it's a timeout if (error instanceof Error && error.name === 'AbortError') { throw new Error(`Request timeout after ${timeoutMs}ms: ${url}`); } throw error; } }