@@ -8,6 +8,7 @@ import TurndownService from "turndown"
88import PCR from "puppeteer-chromium-resolver"
99import { fileExistsAtPath } from "../../utils/fs"
1010import { serializeError } from "serialize-error"
11+ import { isCodespacesEnvironment , fixCodespaceDependencies , isMissingDependencyError } from "./codespaceUtils"
1112
1213// Timeout constants
1314const URL_FETCH_TIMEOUT = 30_000 // 30 seconds
@@ -37,44 +38,115 @@ export class UrlContentFetcher {
3738 if ( ! dirExists ) {
3839 await fs . mkdir ( puppeteerDir , { recursive : true } )
3940 }
40- // if chromium doesn't exist, this will download it to path.join(puppeteerDir, ".chromium-browser-snapshots")
41- // if it does exist it will return the path to existing chromium
42- const stats : PCRStats = await PCR ( {
43- downloadPath : puppeteerDir ,
44- } )
45- return stats
41+
42+ try {
43+ // if chromium doesn't exist, this will download it to path.join(puppeteerDir, ".chromium-browser-snapshots")
44+ // if it does exist it will return the path to existing chromium
45+ const stats : PCRStats = await PCR ( {
46+ downloadPath : puppeteerDir ,
47+ } )
48+ return stats
49+ } catch ( error ) {
50+ // Check if this is a missing dependency error in Codespaces
51+ if ( isCodespacesEnvironment ( ) && isMissingDependencyError ( error ) ) {
52+ console . log ( "Detected missing browser dependencies in Codespaces, attempting to fix..." )
53+
54+ // Try to fix the dependencies
55+ const fixed = await fixCodespaceDependencies ( )
56+
57+ if ( fixed ) {
58+ // Retry PCR after fixing dependencies
59+ console . log ( "Dependencies fixed, retrying browser initialization..." )
60+ const stats : PCRStats = await PCR ( {
61+ downloadPath : puppeteerDir ,
62+ } )
63+ return stats
64+ }
65+ }
66+
67+ // If we couldn't fix it or it's not a Codespaces issue, throw the original error
68+ throw error
69+ }
4670 }
4771
4872 async launchBrowser ( ) : Promise < void > {
4973 if ( this . browser ) {
5074 return
5175 }
52- const stats = await this . ensureChromiumExists ( )
53- const args = [
54- "--user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36" ,
55- "--disable-dev-shm-usage" ,
56- "--disable-accelerated-2d-canvas" ,
57- "--no-first-run" ,
58- "--disable-gpu" ,
59- "--disable-features=VizDisplayCompositor" ,
60- ]
61- if ( process . platform === "linux" ) {
62- // Fixes network errors on Linux hosts (see https://github.com/puppeteer/puppeteer/issues/8246)
63- args . push ( "--no-sandbox" )
64- }
65- this . browser = await stats . puppeteer . launch ( {
66- args,
67- executablePath : stats . executablePath ,
68- } )
69- // (latest version of puppeteer does not add headless to user agent)
70- this . page = await this . browser ?. newPage ( )
71-
72- // Set additional page configurations to improve loading success
73- if ( this . page ) {
74- await this . page . setViewport ( { width : 1280 , height : 720 } )
75- await this . page . setExtraHTTPHeaders ( {
76- "Accept-Language" : "en-US,en;q=0.9" ,
76+
77+ try {
78+ const stats = await this . ensureChromiumExists ( )
79+ const args = [
80+ "--user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36" ,
81+ "--disable-dev-shm-usage" ,
82+ "--disable-accelerated-2d-canvas" ,
83+ "--no-first-run" ,
84+ "--disable-gpu" ,
85+ "--disable-features=VizDisplayCompositor" ,
86+ ]
87+
88+ // Add additional args for Linux/Codespaces environments
89+ if ( process . platform === "linux" || isCodespacesEnvironment ( ) ) {
90+ args . push ( "--no-sandbox" , "--disable-setuid-sandbox" )
91+ }
92+
93+ this . browser = await stats . puppeteer . launch ( {
94+ args,
95+ executablePath : stats . executablePath ,
7796 } )
97+ // (latest version of puppeteer does not add headless to user agent)
98+ this . page = await this . browser ?. newPage ( )
99+
100+ // Set additional page configurations to improve loading success
101+ if ( this . page ) {
102+ await this . page . setViewport ( { width : 1280 , height : 720 } )
103+ await this . page . setExtraHTTPHeaders ( {
104+ "Accept-Language" : "en-US,en;q=0.9" ,
105+ } )
106+ }
107+ } catch ( error ) {
108+ // Check if this is a missing dependency error in Codespaces
109+ if ( isCodespacesEnvironment ( ) && isMissingDependencyError ( error ) ) {
110+ console . log ( "Browser launch failed due to missing dependencies, attempting to fix..." )
111+
112+ // Try to fix the dependencies
113+ const fixed = await fixCodespaceDependencies ( )
114+
115+ if ( fixed ) {
116+ // Retry launching after fixing dependencies
117+ console . log ( "Dependencies fixed, retrying browser launch..." )
118+ const stats = await this . ensureChromiumExists ( )
119+ const args = [
120+ "--user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36" ,
121+ "--disable-dev-shm-usage" ,
122+ "--disable-accelerated-2d-canvas" ,
123+ "--no-first-run" ,
124+ "--disable-gpu" ,
125+ "--disable-features=VizDisplayCompositor" ,
126+ "--no-sandbox" ,
127+ "--disable-setuid-sandbox" ,
128+ ]
129+
130+ this . browser = await stats . puppeteer . launch ( {
131+ args,
132+ executablePath : stats . executablePath ,
133+ } )
134+ // (latest version of puppeteer does not add headless to user agent)
135+ this . page = await this . browser ?. newPage ( )
136+
137+ // Set additional page configurations to improve loading success
138+ if ( this . page ) {
139+ await this . page . setViewport ( { width : 1280 , height : 720 } )
140+ await this . page . setExtraHTTPHeaders ( {
141+ "Accept-Language" : "en-US,en;q=0.9" ,
142+ } )
143+ }
144+ return
145+ }
146+ }
147+
148+ // If we couldn't fix it or it's not a Codespaces issue, throw the original error
149+ throw error
78150 }
79151 }
80152
0 commit comments