Skip to content

Commit 82a0eff

Browse files
ankitsinghkuntal09Ankit Singhcursoragent
authored
feat: W-21111977 consume error-page template from @salesforce/webapp-experimental/proxy (#22)
* feat: consume error-page template from @salesforce/webapp-experimental/proxy @W-21111977@ Update plugin-webapp to import the error page HTML template from the @salesforce/webapp-experimental proxy package instead of bundling it locally. Migration changes: - ErrorPageRenderer now uses getErrorPageTemplate() from @salesforce/webapp-experimental/proxy - Removed local error-page.html template (now lives in webapps package) - Removed scripts/copy-templates.cjs (no longer needed) - Removed postbuild script from package.json - Bumped @salesforce/webapp-experimental dependency to ^1.17.0 Bug fixes included: - DevServerManager: emit DevServerError directly instead of wrapping in SfError, so the proxy can display the "Dev Server Error" page when dev server crashes - ProxyServer: add socket error handler to prevent ECONNRESET from crashing the proxy when dev server dies mid-connection Depends on: salesforce-experience-platform-emu/webapps PR for @W-21111977@ Co-authored-by: Cursor <cursoragent@cursor.com> * feat: W-21111977 consume error-page template from @salesforce/webapp-experimental/proxy Update plugin-webapp to import the error page HTML template from the @salesforce/webapp-experimental proxy package (v1.23.0) instead of bundling it locally. Migration changes: - ErrorPageRenderer now uses getErrorPageTemplate() from @salesforce/webapp-experimental/proxy (direct import, no workarounds) - Removed local error-page.html template (now lives in webapps package) - Removed scripts/copy-templates.cjs (no longer needed) - Removed postbuild script from package.json - Bumped @salesforce/webapp-experimental dependency to ^1.23.0 Bug fixes included: - DevServerManager: emit DevServerError directly instead of wrapping in SfError, so the proxy can display the "Dev Server Error" page when dev server crashes - ProxyServer: add socket error handler to prevent ECONNRESET from crashing the proxy when dev server dies mid-connection - ProxyServer: remove label/version from fallback manifest (not in type) Depends on: salesforce-experience-platform-emu/webapps#86 (merged) Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Ankit Singh <singhankit@singhank-ltmg4lv.internal.salesforce.com> Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 148f795 commit 82a0eff

11 files changed

Lines changed: 40 additions & 898 deletions

File tree

package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"@salesforce/core": "^8.25.0",
1111
"@salesforce/kit": "^3.2.4",
1212
"@salesforce/sf-plugins-core": "^12.2.6",
13-
"@salesforce/webapp-experimental": "^0.2.0",
13+
"@salesforce/webapp-experimental": "^1.23.0",
1414
"chokidar": "^3.6.0",
1515
"http-proxy": "^1.18.1",
1616
"micromatch": "^4.0.8",
@@ -78,7 +78,6 @@
7878
"format": "wireit",
7979
"link-check": "wireit",
8080
"lint": "wireit",
81-
"postbuild": "node scripts/copy-templates.cjs",
8281
"postpack": "sf-clean --ignore-signing-artifacts",
8382
"prepack": "sf-prepack",
8483
"prepare": "sf-install",

scripts/copy-templates.cjs

Lines changed: 0 additions & 31 deletions
This file was deleted.

src/proxy/ProxyServer.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,11 @@ export class ProxyServer extends EventEmitter {
176176

177177
this.server.on('connection', (socket) => {
178178
this.activeConnections.add(socket);
179+
socket.on('error', (err) => {
180+
// Handle ECONNRESET and other socket errors gracefully
181+
// These can happen when the dev server crashes or a client disconnects abruptly
182+
this.logger.debug(`Socket error (${err.message}), cleaning up connection`);
183+
});
179184
socket.once('close', () => {
180185
this.activeConnections.delete(socket);
181186
});
@@ -407,8 +412,6 @@ export class ProxyServer extends EventEmitter {
407412
private initializeProxyHandler(): void {
408413
const manifest: WebAppManifest = this.config.manifest ?? {
409414
name: 'webapp',
410-
label: 'WebApp',
411-
version: '1.0.0',
412415
outputDir: 'dist',
413416
};
414417

src/server/DevServerManager.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -429,11 +429,10 @@ export class DevServerManager extends EventEmitter {
429429
this.logger.error(`Dev server error: ${parsedError.title}`);
430430
this.logger.debug(`Error type: ${parsedError.type}`);
431431

432-
// Convert to SfError for proper error handling
433-
// Use just the message (not title) since title will be shown separately
434-
const sfError = new SfError(parsedError.message, 'DevServerError', parsedError.suggestions);
435-
436-
this.emit('error', sfError);
432+
// Emit the parsed DevServerError directly so the receiver (dev.ts)
433+
// can access stderrLines, title, and type for the error page.
434+
// Previously this was wrapped in SfError which lost those properties.
435+
this.emit('error', parsedError);
437436
}
438437

439438
// Reset state

src/templates/ErrorPageRenderer.ts

Lines changed: 2 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
import { readFileSync } from 'node:fs';
18-
import { join, dirname } from 'node:path';
19-
import { fileURLToPath } from 'node:url';
17+
import { getErrorPageTemplate } from '@salesforce/webapp-experimental/proxy';
2018
import type { DevServerError } from '../config/types.js';
2119

2220
export type ErrorPageData = {
@@ -37,55 +35,7 @@ export class ErrorPageRenderer {
3735
private template: string;
3836

3937
public constructor() {
40-
// Load the HTML template
41-
const currentDir = dirname(fileURLToPath(import.meta.url));
42-
const templatePath = join(currentDir, 'error-page.html');
43-
44-
try {
45-
this.template = readFileSync(templatePath, 'utf-8');
46-
} catch (error) {
47-
// Log warning but don't crash - use minimal fallback template
48-
// eslint-disable-next-line no-console
49-
console.error(`[ErrorPageRenderer] Failed to load template from ${templatePath}:`, error);
50-
this.template = ErrorPageRenderer.getMinimalFallbackTemplate();
51-
}
52-
}
53-
54-
/**
55-
* Minimal fallback template used when the main template file cannot be loaded.
56-
* This ensures the proxy can still display error pages even if the template is missing.
57-
*/
58-
private static getMinimalFallbackTemplate(): string {
59-
return `<!DOCTYPE html>
60-
<html lang="en">
61-
<head>
62-
<meta charset="UTF-8">
63-
<title>{{PAGE_TITLE}}</title>
64-
{{META_REFRESH}}
65-
<style>
66-
body { font-family: system-ui, sans-serif; background: #1a1a2e; color: #eee; padding: 40px; }
67-
.container { max-width: 800px; margin: 0 auto; }
68-
h1 { color: #ff6b6b; }
69-
.status { color: #ffd93d; margin-bottom: 20px; }
70-
.info { background: #16213e; padding: 20px; border-radius: 8px; margin: 20px 0; }
71-
.info p { margin: 8px 0; }
72-
code { background: #0f3460; padding: 2px 6px; border-radius: 4px; }
73-
</style>
74-
</head>
75-
<body>
76-
<div class="container">
77-
<h1>{{ERROR_TITLE}}</h1>
78-
<p class="status">{{ERROR_STATUS}}</p>
79-
<div class="info">
80-
{{MESSAGE_CONTENT}}
81-
<p><strong>Dev Server:</strong> <code>{{DEV_SERVER_URL}}</code></p>
82-
<p><strong>Proxy:</strong> <code>{{PROXY_URL}}</code></p>
83-
<p><strong>Last Check:</strong> {{LAST_CHECK_TIME}}</p>
84-
</div>
85-
<p style="color:#888;font-size:14px;">{{AUTO_REFRESH_TEXT}}</p>
86-
</div>
87-
</body>
88-
</html>`;
38+
this.template = getErrorPageTemplate();
8939
}
9040

9141
/**

0 commit comments

Comments
 (0)