Skip to content

Commit d326b31

Browse files
fix(dev): resolve Ctrl+C not exiting when using explicit URL mode
- Use prependOnceListener for SIGINT/SIGTERM before sfCommand handlers - Ensures graceful shutdown when no dev server is spawned - Works with explicit URL in webapp.json or --url flag - Revert .gitignore changes (documentation files removed)
1 parent ccf50a7 commit d326b31

2 files changed

Lines changed: 21 additions & 10 deletions

File tree

.gitignore

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,8 @@ lib
2222
coverage
2323
test_session*
2424

25-
# generated docs (but allow markdown documentation)
25+
# generated docs
2626
docs
27-
!docs/*.md
28-
!docs/README.md
2927

3028
# ignore sfdx-trust files
3129
*.tgz

src/commands/webapp/dev.ts

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -298,15 +298,28 @@ export default class WebappDev extends SfCommand<WebAppDevResult> {
298298
// Keep the command running until interrupted or dev server exits
299299
await new Promise<void>((resolve) => {
300300
// Exit if dev server exits with SIGINT (user pressed Ctrl+C)
301-
this.devServerManager?.on('exit', (code: number | null, signal: string | null) => {
302-
if (signal === 'SIGINT') {
303-
this.logger?.debug('Dev server received SIGINT, exiting command');
304-
resolve();
305-
}
301+
if (this.devServerManager) {
302+
this.devServerManager.on('exit', (code: number | null, signal: string | null) => {
303+
if (signal === 'SIGINT') {
304+
this.logger?.debug('Dev server received SIGINT, exiting command');
305+
resolve();
306+
}
307+
});
308+
}
309+
310+
// CRITICAL: Use prependOnceListener to add our handlers BEFORE sfCommand's handlers
311+
// sfCommand adds process.on('SIGINT', () => this.exit(130)) which throws ExitError
312+
// By using prependOnceListener, our resolve() runs FIRST, allowing clean shutdown
313+
// This is especially important when there's no dev server (explicit URL mode)
314+
process.prependOnceListener('SIGINT', () => {
315+
this.logger?.debug('Received SIGINT signal, initiating graceful shutdown');
316+
resolve();
306317
});
307318

308-
// The command will also exit on process SIGINT/SIGTERM
309-
// which triggers the finally() cleanup
319+
process.prependOnceListener('SIGTERM', () => {
320+
this.logger?.debug('Received SIGTERM signal, initiating graceful shutdown');
321+
resolve();
322+
});
310323
});
311324

312325
// Return result (never reached, but required for type safety)

0 commit comments

Comments
 (0)