ソースを参照

Close browser even if screenshot fails; handle case where webp screenshot fails

Saoud Rizwan 1 年間 前
コミット
46ceafa016
2 ファイル変更38 行追加6 行削除
  1. 10 2
      src/ClaudeDev.ts
  2. 28 4
      src/utils/UrlContentFetcher.ts

+ 10 - 2
src/ClaudeDev.ts

@@ -1471,8 +1471,16 @@ export class ClaudeDev {
 
 			await this.say("inspect_site_result", "") // no result, starts the loading spinner waiting for result
 			await this.urlContentFetcher.launchBrowser()
-			const { screenshot, logs } = await this.urlContentFetcher.urlToScreenshotAndLogs(url)
-			await this.urlContentFetcher.closeBrowser()
+			let result: {
+				screenshot: string
+				logs: string
+			}
+			try {
+				result = await this.urlContentFetcher.urlToScreenshotAndLogs(url)
+			} finally {
+				await this.urlContentFetcher.closeBrowser()
+			}
+			const { screenshot, logs } = result
 			await this.say("inspect_site_result", logs, [screenshot])
 
 			return [

+ 28 - 4
src/utils/UrlContentFetcher.ts

@@ -1,7 +1,7 @@
 import * as vscode from "vscode"
 import * as fs from "fs/promises"
 import * as path from "path"
-import { Browser, Page, TimeoutError, launch } from "puppeteer-core"
+import { Browser, Page, ScreenshotOptions, TimeoutError, launch } from "puppeteer-core"
 import * as cheerio from "cheerio"
 import TurndownService from "turndown"
 // @ts-ignore
@@ -130,14 +130,38 @@ export class UrlContentFetcher {
 			interval: 100,
 		}).catch(() => {})
 
-		const screenshotBase64 = await this.page.screenshot({
+		// image cannot exceed 8_000 pixels
+		const pageHeight = await this.page.evaluate(() => document.documentElement.scrollHeight)
+		let options: ScreenshotOptions = {
 			fullPage: true,
-			type: "webp",
 			encoding: "base64",
 			// quality: 80,
+			clip: {
+				x: 0,
+				y: 0,
+				width: await this.page.evaluate(() => document.documentElement.clientWidth),
+				height: Math.min(pageHeight, 8_000),
+			},
+		}
+
+		let screenshotBase64 = await this.page.screenshot({
+			...options,
+			type: "webp",
 		})
+		let screenshot = `data:image/webp;base64,${screenshotBase64}`
+
+		if (!screenshotBase64) {
+			console.log("webp screenshot failed, trying png")
+			screenshotBase64 = await this.page.screenshot({
+				...options,
+				type: "png",
+			})
+			screenshot = `data:image/png;base64,${screenshotBase64}`
+		}
 
-		const screenshot = `data:image/webp;base64,${screenshotBase64}`
+		if (!screenshotBase64) {
+			throw new Error("Failed to take screenshot.")
+		}
 
 		this.page.removeAllListeners()