@@ -38,7 +38,7 @@ interface ProxyOptions {
3838 password ?: string | undefined ;
3939}
4040
41- async function launchBrowser (
41+ async function launchBrowserOnce (
4242 config : WorkerConfig ,
4343) : Promise < { browser : Browser ; context : BrowserContext ; page : Page } > {
4444 const viewport : { height : number ; width : number } =
@@ -98,9 +98,43 @@ async function launchBrowser(
9898
9999 const page : Page = await context . newPage ( ) ;
100100
101+ // Set default timeouts so page operations don't hang indefinitely
102+ page . setDefaultTimeout ( config . timeout ) ;
103+ page . setDefaultNavigationTimeout ( config . timeout ) ;
104+
101105 return { browser, context, page } ;
102106}
103107
108+ const MAX_BROWSER_LAUNCH_RETRIES : number = 3 ;
109+ const BROWSER_LAUNCH_RETRY_DELAY_MS : number = 2000 ;
110+
111+ async function launchBrowser (
112+ config : WorkerConfig ,
113+ ) : Promise < { browser : Browser ; context : BrowserContext ; page : Page } > {
114+ let lastError : Error | undefined ;
115+
116+ for ( let attempt : number = 1 ; attempt <= MAX_BROWSER_LAUNCH_RETRIES ; attempt ++ ) {
117+ try {
118+ return await launchBrowserOnce ( config ) ;
119+ } catch ( err : unknown ) {
120+ lastError = err as Error ;
121+
122+ // If this is not the last attempt, wait before retrying
123+ if ( attempt < MAX_BROWSER_LAUNCH_RETRIES ) {
124+ await new Promise ( ( resolve : ( value : void ) => void ) => {
125+ setTimeout ( resolve , BROWSER_LAUNCH_RETRY_DELAY_MS ) ;
126+ } ) ;
127+ }
128+ }
129+ }
130+
131+ throw new Error (
132+ `Failed to launch browser after ${ MAX_BROWSER_LAUNCH_RETRIES } attempts. ` +
133+ `This is usually caused by insufficient memory in the container. ` +
134+ `Last error: ${ lastError ?. message || String ( lastError ) } ` ,
135+ ) ;
136+ }
137+
104138async function run ( config : WorkerConfig ) : Promise < WorkerResult > {
105139 const workerResult : WorkerResult = {
106140 logMessages : [ ] ,
0 commit comments