Merge pull request #498 from getmaxun/context-fix

fix: handling unexpected browser context closed error
This commit is contained in:
Karishma Shukla
2025-03-27 16:02:24 +05:30
committed by GitHub

View File

@@ -268,6 +268,12 @@ export class RemoteBrowser {
* @returns {Promise<void>} * @returns {Promise<void>}
*/ */
public initialize = async (userId: string): Promise<void> => { public initialize = async (userId: string): Promise<void> => {
const MAX_RETRIES = 3;
let retryCount = 0;
let success = false;
while (!success && retryCount < MAX_RETRIES) {
try {
this.browser = <Browser>(await chromium.launch({ this.browser = <Browser>(await chromium.launch({
headless: true, headless: true,
args: [ args: [
@@ -282,8 +288,14 @@ export class RemoteBrowser {
"--force-device-scale-factor=2", "--force-device-scale-factor=2",
], ],
})); }));
if (!this.browser || this.browser.isConnected() === false) {
throw new Error('Browser failed to launch or is not connected');
}
const proxyConfig = await getDecryptedProxyConfig(userId); const proxyConfig = await getDecryptedProxyConfig(userId);
let proxyOptions: { server: string, username?: string, password?: string } = { server: '' }; let proxyOptions: { server: string, username?: string, password?: string } = { server: '' };
if (proxyConfig.proxy_url) { if (proxyConfig.proxy_url) {
proxyOptions = { proxyOptions = {
server: proxyConfig.proxy_url, server: proxyConfig.proxy_url,
@@ -293,6 +305,7 @@ export class RemoteBrowser {
}), }),
}; };
} }
const contextOptions: any = { const contextOptions: any = {
// viewport: { height: 400, width: 900 }, // viewport: { height: 400, width: 900 },
// recordVideo: { dir: 'videos/' } // recordVideo: { dir: 'videos/' }
@@ -318,7 +331,16 @@ export class RemoteBrowser {
}; };
} }
this.context = await this.browser.newContext(contextOptions); await new Promise(resolve => setTimeout(resolve, 500));
const contextPromise = this.browser.newContext(contextOptions);
this.context = await Promise.race([
contextPromise,
new Promise<never>((_, reject) => {
setTimeout(() => reject(new Error('Context creation timed out after 15s')), 15000);
})
]) as BrowserContext;
await this.context.addInitScript( await this.context.addInitScript(
`const defaultGetter = Object.getOwnPropertyDescriptor( `const defaultGetter = Object.getOwnPropertyDescriptor(
Navigator.prototype, Navigator.prototype,
@@ -344,8 +366,8 @@ export class RemoteBrowser {
patchedGetter.apply(navigator); patchedGetter.apply(navigator);
patchedGetter.toString();` patchedGetter.toString();`
); );
this.currentPage = await this.context.newPage();
this.currentPage = await this.context.newPage();
await this.setupPageEventListeners(this.currentPage); await this.setupPageEventListeners(this.currentPage);
const viewportSize = await this.currentPage.viewportSize(); const viewportSize = await this.currentPage.viewportSize();
@@ -369,6 +391,29 @@ export class RemoteBrowser {
this.client = await this.currentPage.context().newCDPSession(this.currentPage); this.client = await this.currentPage.context().newCDPSession(this.currentPage);
} }
success = true;
logger.log('debug', `Browser initialized successfully for user ${userId}`);
} catch (error: any) {
retryCount++;
logger.log('error', `Browser initialization failed (attempt ${retryCount}/${MAX_RETRIES}): ${error.message}`);
if (this.browser) {
try {
await this.browser.close();
} catch (closeError) {
logger.log('warn', `Failed to close browser during cleanup: ${closeError}`);
}
this.browser = null;
}
if (retryCount >= MAX_RETRIES) {
throw new Error(`Failed to initialize browser after ${MAX_RETRIES} attempts: ${error.message}`);
}
await new Promise(resolve => setTimeout(resolve, 1000));
}
}
this.initializeMemoryManagement(); this.initializeMemoryManagement();
}; };