Skip to content

Commit 78f659f

Browse files
author
pengyu
committed
fix the problem doesn't allow for screenshot
1 parent b052c91 commit 78f659f

File tree

3 files changed

+40
-29
lines changed

3 files changed

+40
-29
lines changed

docker/project-base-image/Dockerfile

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@ WORKDIR /app
55
# Pre-install common frontend dependencies to speed up project startup
66
RUN npm install -g npm@latest vite@latest
77

8-
# Create a non-root user to run the app
9-
RUN groupadd -r appuser && useradd -r -g appuser -m appuser
10-
RUN chown -R appuser:appuser /app
8+
#TODO: Uncomment this when we have a non-root usr (Allen)
9+
# #Create a non-root user to run the app
10+
# RUN groupadd -r appuser && useradd -r -g appuser -m appuser
11+
# RUN chown -R appuser:appuser /app
12+
# RUN chmod -R u+w /app
1113

12-
# Switch to non-root user for security
13-
USER appuser
14+
# # Switch to non-root user for security
15+
# USER appuser
1416

1517
EXPOSE 5173
1618

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

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ async function getBrowser(): Promise<Browser> {
1414
protocolTimeout: 240000,
1515
args: ['--no-sandbox', '--disable-setuid-sandbox'],
1616
});
17+
} else {
18+
logger.info('Reusing existing browser instance...');
1719
}
1820
return browserInstance;
1921
}
@@ -24,45 +26,51 @@ export async function GET(req: Request) {
2426
let page = null;
2527

2628
if (!url) {
29+
logger.warn('No URL provided in query parameters');
2730
return NextResponse.json(
2831
{ error: 'URL parameter is required' },
2932
{ status: 400 }
3033
);
3134
}
3235

36+
logger.info(`Starting screenshot for URL: ${url}`);
37+
3338
try {
3439
// Get browser instance
3540
const browser = await getBrowser();
41+
logger.info('Browser instance acquired');
3642

3743
// Create a new page
3844
page = await browser.newPage();
45+
logger.info('New page created');
3946

40-
// Set viewport to a reasonable size
41-
await page.setViewport({
42-
width: 1600,
43-
height: 900,
44-
});
47+
// Set viewport
48+
await page.setViewport({ width: 1600, height: 900 });
49+
logger.info('Viewport set to 1600x900');
4550

46-
// Navigate to URL with increased timeout and more reliable wait condition
51+
// Navigate to the URL
52+
logger.info(`Navigating to URL: ${url}`);
4753
await page.goto(url, {
48-
waitUntil: 'domcontentloaded', // Less strict than networkidle0
49-
timeout: 60000, // Increased timeout to 60 seconds
54+
waitUntil: 'domcontentloaded',
55+
timeout: 60000,
5056
});
57+
logger.info('Page loaded (DOMContentLoaded)');
5158

52-
await new Promise((resolve) => setTimeout(resolve, 2000)); // Waits for 2 seconds
59+
// Extra wait for rendering
60+
await new Promise((resolve) => setTimeout(resolve, 2000));
61+
logger.info('Waited 2 seconds for rendering');
5362

5463
// Take screenshot
5564
const screenshot = await page.screenshot({
5665
type: 'png',
5766
fullPage: true,
5867
});
68+
logger.info('Screenshot captured');
5969

60-
// Always close the page when done
61-
if (page) {
62-
await page.close();
63-
}
70+
// Clean up
71+
if (page) await page.close();
72+
logger.info('Page closed');
6473

65-
// Return the screenshot as a PNG image
6674
return new Response(screenshot, {
6775
headers: {
6876
'Content-Type': 'image/png',
@@ -72,24 +80,24 @@ export async function GET(req: Request) {
7280
} catch (error: any) {
7381
logger.error('Screenshot error:', error);
7482

75-
// Ensure page is closed even if an error occurs
7683
if (page) {
7784
try {
7885
await page.close();
86+
logger.info('Closed page after error');
7987
} catch (closeError) {
8088
logger.error('Error closing page:', closeError);
8189
}
8290
}
8391

84-
// If browser seems to be in a bad state, recreate it
8592
if (
86-
error.message.includes('Target closed') ||
87-
error.message.includes('Protocol error') ||
88-
error.message.includes('Target.createTarget')
93+
error.message?.includes('Target closed') ||
94+
error.message?.includes('Protocol error') ||
95+
error.message?.includes('Target.createTarget')
8996
) {
9097
try {
9198
if (browserInstance) {
9299
await browserInstance.close();
100+
logger.warn('Browser instance was closed due to protocol error');
93101
browserInstance = null;
94102
}
95103
} catch (closeBrowserError) {
@@ -104,12 +112,12 @@ export async function GET(req: Request) {
104112
}
105113
}
106114

107-
// Handle process termination to close browser
115+
// Gracefully close the browser when the process exits
108116
process.on('SIGINT', async () => {
109117
if (browserInstance) {
110-
logger.info('Closing browser instance...');
118+
logger.info('SIGINT received. Closing browser instance...');
111119
await browserInstance.close();
112120
browserInstance = null;
113121
}
114122
process.exit(0);
115-
});
123+
});

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -635,8 +635,9 @@ export function ProjectProvider({ children }: { children: ReactNode }) {
635635

636636
const blob = new Blob([arrayBuffer], { type: 'image/png' });
637637
const file = new File([blob], 'screenshot.png', { type: 'image/png' });
638+
639+
//change to true work
638640

639-
if (isMounted.current) {
640641
logger.debug(`[screenshot] Calling mutation to update photoUrl for Project ${projectId}`);
641642
await updateProjectPhotoMutation({
642643
variables: {
@@ -647,7 +648,7 @@ export function ProjectProvider({ children }: { children: ReactNode }) {
647648
},
648649
});
649650
logger.debug(`[screenshot] photoUrl updated successfully for Project ${projectId}`);
650-
}
651+
651652
} catch (error) {
652653
logger.error(`[screenshot] Error for Project ${projectId}:`, error);
653654
} finally {

0 commit comments

Comments
 (0)