Skip to content

Commit b052c91

Browse files
author
pengyu
committed
revert route
1 parent 4d055b0 commit b052c91

File tree

3 files changed

+79
-129
lines changed

3 files changed

+79
-129
lines changed

frontend/src/app/api/runProject/route.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -517,12 +517,10 @@ export async function GET(req: Request) {
517517
existingContainer.containerId
518518
);
519519
if (isRunning) {
520-
logger.info(`Using existing container with port: ${existingContainer.port}`);
521520
return NextResponse.json({
522521
message: 'Docker container already running',
523522
domain: existingContainer.domain,
524523
containerId: existingContainer.containerId,
525-
port: existingContainer.port,
526524
});
527525
} else {
528526
// Remove non-running container from state
@@ -549,14 +547,12 @@ export async function GET(req: Request) {
549547
processingRequests.add(projectPath);
550548

551549
try {
552-
const { domain, containerId, port } = await runDockerContainer(projectPath);
553-
logger.info(`Successfully started container on port: ${port}`);
550+
const { domain, containerId } = await runDockerContainer(projectPath);
554551

555552
return NextResponse.json({
556553
message: 'Docker container started',
557554
domain,
558555
containerId,
559-
port,
560556
});
561557
} catch (error: any) {
562558
logger.error(`Failed to start Docker container:`, error);
@@ -567,4 +563,4 @@ export async function GET(req: Request) {
567563
} finally {
568564
processingRequests.delete(projectPath);
569565
}
570-
}
566+
}

frontend/src/app/api/screenshot/route.ts

Lines changed: 58 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ export async function GET(req: Request) {
2222
const { searchParams } = new URL(req.url);
2323
const url = searchParams.get('url');
2424
let page = null;
25-
const MAX_RETRIES = 3;
2625

2726
if (!url) {
2827
return NextResponse.json(
@@ -31,130 +30,78 @@ export async function GET(req: Request) {
3130
);
3231
}
3332

34-
for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {
35-
try {
36-
logger.info(`Screenshot attempt ${attempt + 1} for ${url}`);
37-
38-
// Get browser instance
39-
const browser = await getBrowser();
33+
try {
34+
// Get browser instance
35+
const browser = await getBrowser();
4036

41-
// Create a new page
42-
page = await browser.newPage();
37+
// Create a new page
38+
page = await browser.newPage();
4339

44-
// Set viewport to a reasonable size
45-
await page.setViewport({
46-
width: 1280,
47-
height: 720,
48-
});
40+
// Set viewport to a reasonable size
41+
await page.setViewport({
42+
width: 1600,
43+
height: 900,
44+
});
4945

50-
// Navigate to URL with increased timeout and more reliable wait condition
51-
await page.goto(url, {
52-
waitUntil: 'networkidle2', // 更改为等待网络空闲状态,确保页面完全加载
53-
timeout: 90000, // 增加超时时间到90秒
54-
});
46+
// Navigate to URL with increased timeout and more reliable wait condition
47+
await page.goto(url, {
48+
waitUntil: 'domcontentloaded', // Less strict than networkidle0
49+
timeout: 60000, // Increased timeout to 60 seconds
50+
});
5551

56-
// 等待额外的时间让页面完全渲染
57-
await page.waitForTimeout(8000); // 增加等待时间到8秒
52+
await new Promise((resolve) => setTimeout(resolve, 2000)); // Waits for 2 seconds
5853

59-
// 尝试等待页面上的内容加载,如果失败也继续处理
60-
try {
61-
// 等待页面上可能存在的主要内容元素
62-
await Promise.race([
63-
page.waitForSelector('main', { timeout: 5000 }),
64-
page.waitForSelector('#root', { timeout: 5000 }),
65-
page.waitForSelector('.app', { timeout: 5000 }),
66-
page.waitForSelector('h1', { timeout: 5000 }),
67-
page.waitForSelector('div', { timeout: 5000 }), // 添加更通用的选择器
68-
]);
69-
} catch (waitError) {
70-
// 忽略等待选择器的错误,继续截图
71-
logger.info('Unable to find common page elements, continuing with screenshot');
72-
}
54+
// Take screenshot
55+
const screenshot = await page.screenshot({
56+
type: 'png',
57+
fullPage: true,
58+
});
7359

74-
// 检查页面是否有内容
75-
const contentCheck = await page.evaluate(() => {
76-
return {
77-
bodyContent: document.body.innerText.length,
78-
elements: document.querySelectorAll('*').length
79-
};
80-
});
81-
82-
logger.info(`Page content: ${contentCheck.bodyContent} chars, ${contentCheck.elements} elements`);
83-
84-
if (contentCheck.elements < 5) {
85-
logger.warn('Page seems empty, possibly not fully loaded');
86-
if (attempt < MAX_RETRIES - 1) {
87-
await page.close();
88-
continue; // 重试
89-
}
90-
}
60+
// Always close the page when done
61+
if (page) {
62+
await page.close();
63+
}
9164

92-
// Take screenshot with full page height
93-
const screenshot = await page.screenshot({
94-
type: 'png',
95-
fullPage: false,
96-
});
65+
// Return the screenshot as a PNG image
66+
return new Response(screenshot, {
67+
headers: {
68+
'Content-Type': 'image/png',
69+
'Cache-Control': 's-maxage=3600',
70+
},
71+
});
72+
} catch (error: any) {
73+
logger.error('Screenshot error:', error);
9774

98-
// Always close the page when done
99-
if (page) {
75+
// Ensure page is closed even if an error occurs
76+
if (page) {
77+
try {
10078
await page.close();
79+
} catch (closeError) {
80+
logger.error('Error closing page:', closeError);
10181
}
82+
}
10283

103-
// Return the screenshot as a PNG image
104-
return new Response(screenshot, {
105-
headers: {
106-
'Content-Type': 'image/png',
107-
'Cache-Control': 's-maxage=3600',
108-
},
109-
});
110-
} catch (error: any) {
111-
logger.error(`Screenshot error on attempt ${attempt + 1}:`, error);
112-
113-
// Ensure page is closed even if an error occurs
114-
if (page) {
115-
try {
116-
await page.close();
117-
} catch (closeError) {
118-
logger.error('Error closing page:', closeError);
119-
}
120-
}
121-
122-
// If browser seems to be in a bad state, recreate it
123-
if (
124-
error.message.includes('Target closed') ||
125-
error.message.includes('Protocol error') ||
126-
error.message.includes('Target.createTarget')
127-
) {
128-
try {
129-
if (browserInstance) {
130-
await browserInstance.close();
131-
browserInstance = null;
132-
}
133-
} catch (closeBrowserError) {
134-
logger.error('Error closing browser:', closeBrowserError);
84+
// If browser seems to be in a bad state, recreate it
85+
if (
86+
error.message.includes('Target closed') ||
87+
error.message.includes('Protocol error') ||
88+
error.message.includes('Target.createTarget')
89+
) {
90+
try {
91+
if (browserInstance) {
92+
await browserInstance.close();
93+
browserInstance = null;
13594
}
95+
} catch (closeBrowserError) {
96+
logger.error('Error closing browser:', closeBrowserError);
13697
}
137-
138-
// 如果这不是最后一次尝试,则继续
139-
if (attempt < MAX_RETRIES - 1) {
140-
// 等待一会儿再重试
141-
await new Promise(resolve => setTimeout(resolve, 3000));
142-
continue;
143-
}
144-
145-
// 最后一次尝试失败
146-
return NextResponse.json(
147-
{ error: error.message || 'Failed to capture screenshot after multiple attempts' },
148-
{ status: 500 }
149-
);
15098
}
151-
}
15299

153-
// 如果重试都失败
154-
return NextResponse.json(
155-
{ error: 'Failed to capture screenshot after exhausting all retries' },
156-
{ status: 500 }
157-
);
100+
return NextResponse.json(
101+
{ error: error.message || 'Failed to capture screenshot' },
102+
{ status: 500 }
103+
);
104+
}
158105
}
159106

160107
// Handle process termination to close browser
@@ -165,4 +112,4 @@ process.on('SIGINT', async () => {
165112
browserInstance = null;
166113
}
167114
process.exit(0);
168-
});
115+
});

frontend/src/components/chat/code-engine/project-context.tsx

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -603,37 +603,41 @@ export function ProjectProvider({ children }: { children: ReactNode }) {
603603

604604
const takeProjectScreenshot = useCallback(
605605
async (projectId: string, url: string): Promise<void> => {
606-
// Check if this screenshot operation is already in progress
607606
const operationKey = `screenshot_${projectId}`;
608607
if (pendingOperations.current.get(operationKey)) {
608+
logger.debug(`[screenshot] Project ${projectId} is already being processed`);
609609
return;
610610
}
611-
611+
612612
pendingOperations.current.set(operationKey, true);
613-
613+
logger.debug(`[screenshot] Start for Project ${projectId}, URL: ${url}`);
614+
614615
try {
615-
// Check if the URL is accessible
616+
logger.debug(`[screenshot] Checking accessibility for ${url}`);
616617
const isUrlAccessible = await checkUrlStatus(url);
617618
if (!isUrlAccessible) {
618-
logger.warn(`URL ${url} is not accessible after multiple retries`);
619+
logger.warn(`[screenshot] URL ${url} is not accessible after retries`);
619620
return;
620621
}
621-
622-
// Add a cache buster to avoid previous screenshot caching
622+
623623
const screenshotUrl = `/api/screenshot?url=${encodeURIComponent(url)}&t=${Date.now()}`;
624+
logger.debug(`[screenshot] Sending request to ${screenshotUrl}`);
624625
const screenshotResponse = await fetch(screenshotUrl);
625-
626+
626627
if (!screenshotResponse.ok) {
627628
throw new Error(
628-
`Failed to capture screenshot: ${screenshotResponse.status} ${screenshotResponse.statusText}`
629+
`[screenshot] Failed to capture: ${screenshotResponse.status} ${screenshotResponse.statusText}`
629630
);
630631
}
631-
632+
632633
const arrayBuffer = await screenshotResponse.arrayBuffer();
634+
logger.debug(`[screenshot] Screenshot captured for Project ${projectId}, uploading...`);
635+
633636
const blob = new Blob([arrayBuffer], { type: 'image/png' });
634637
const file = new File([blob], 'screenshot.png', { type: 'image/png' });
635-
638+
636639
if (isMounted.current) {
640+
logger.debug(`[screenshot] Calling mutation to update photoUrl for Project ${projectId}`);
637641
await updateProjectPhotoMutation({
638642
variables: {
639643
input: {
@@ -642,15 +646,18 @@ export function ProjectProvider({ children }: { children: ReactNode }) {
642646
},
643647
},
644648
});
649+
logger.debug(`[screenshot] photoUrl updated successfully for Project ${projectId}`);
645650
}
646651
} catch (error) {
647-
logger.error('Error taking screenshot:', error);
652+
logger.error(`[screenshot] Error for Project ${projectId}:`, error);
648653
} finally {
654+
logger.debug(`[screenshot] Finished process for Project ${projectId}`);
649655
pendingOperations.current.delete(operationKey);
650656
}
651657
},
652658
[updateProjectPhotoMutation]
653659
);
660+
654661

655662
const getWebUrl = useCallback(
656663
async (

0 commit comments

Comments
 (0)