feat: launch local browser fallback

This commit is contained in:
Rohit Rajan
2025-11-30 17:55:50 +05:30
parent cf19a72dc0
commit 3018d7dc3a

View File

@@ -41,15 +41,56 @@ async function getBrowserServiceEndpoint(): Promise<string> {
}
/**
* Connect to the remote browser service with retry logic
* Launch a local browser as fallback when browser service is unavailable
* @returns Promise<Browser> - Locally launched browser instance
*/
async function launchLocalBrowser(): Promise<Browser> {
logger.warn('Attempting to launch local browser');
logger.warn('Note: This requires Chromium binaries to be installed (npx playwright install chromium)');
try {
const browser = await chromium.launch({
headless: true,
args: [
'--disable-blink-features=AutomationControlled',
'--disable-web-security',
'--disable-features=IsolateOrigins,site-per-process',
'--disable-site-isolation-trials',
'--disable-extensions',
'--no-sandbox',
'--disable-dev-shm-usage',
'--disable-gpu',
'--force-color-profile=srgb',
'--force-device-scale-factor=2',
'--ignore-certificate-errors',
'--mute-audio'
],
});
logger.info('Successfully launched local browser');
return browser;
} catch (error: any) {
logger.error(`Failed to launch local browser: ${error.message}`);
throw new Error(
`Could not launch local browser. ` +
`Please either:\n` +
` 1. Start the browser service: docker-compose up browser\n` +
` 2. Install Chromium binaries: npx playwright@1.57.0 install chromium`
);
}
}
/**
* Connect to the remote browser service with retry logic, with fallback to local browser
* @param retries - Number of connection attempts (default: 3)
* @returns Promise<Browser> - Connected browser instance
* @throws Error if connection fails after all retries
* @returns Promise<Browser> - Connected browser instance (remote or local)
* @throws Error if both remote connection and local launch fail
*/
export async function connectToRemoteBrowser(retries?: number): Promise<Browser> {
const maxRetries = retries ?? CONNECTION_CONFIG.maxRetries;
const wsEndpoint = await getBrowserServiceEndpoint();
try {
const wsEndpoint = await getBrowserServiceEndpoint();
logger.info(`Connecting to browser service at ${wsEndpoint}...`);
for (let attempt = 1; attempt <= maxRetries; attempt++) {
@@ -60,7 +101,7 @@ export async function connectToRemoteBrowser(retries?: number): Promise<Browser>
timeout: CONNECTION_CONFIG.connectionTimeout,
});
logger.info(`Successfully connected to browser service`);
logger.info('Successfully connected to browser service');
return browser;
} catch (error: any) {
logger.warn(
@@ -71,9 +112,7 @@ export async function connectToRemoteBrowser(retries?: number): Promise<Browser>
logger.error(
`Failed to connect to browser service after ${maxRetries} attempts`
);
throw new Error(
`Failed to connect to browser service at ${wsEndpoint}: ${error.message}`
);
throw new Error(`Remote connection failed: ${error.message}`);
}
logger.debug(`Waiting ${CONNECTION_CONFIG.retryDelay}ms before retry...`);
@@ -82,6 +121,12 @@ export async function connectToRemoteBrowser(retries?: number): Promise<Browser>
}
throw new Error('Failed to connect to browser service');
} catch (error: any) {
logger.warn(`Browser service connection failed: ${error.message}`);
logger.warn('Falling back to local browser launch...');
return await launchLocalBrowser();
}
}
/**