Conversation
When users press Ctrl+C to exit `shopify theme dev`, the process immediately called `process.exit()`, terminating before the oclif post-run hook could send analytics events. Fix by resolving the background job promise on Ctrl+C instead of exiting directly, allowing the promise chain to complete and analytics to fire before exit.
43acc70 to
1e43830
Compare
There was a problem hiding this comment.
Pull request overview
This PR aims to restore/ensure analytics capture for shopify theme dev sessions when users exit via Ctrl+C by switching from an immediate process.exit() to a “graceful shutdown” signal that allows the command lifecycle to complete.
Changes:
- Changed the dev server “background job” promise to be resolvable (
Promise<void>) and exposed its resolver to callers. - Updated the Ctrl+C keypress handler to invoke an
onClosecallback instead of callingprocess.exit()directly. - Added a changeset entry and a unit test asserting Ctrl+C triggers
onClose.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| packages/theme/src/cli/utilities/theme-environment/theme-environment.ts | Makes the background-job promise resolvable and returns its resolver. |
| packages/theme/src/cli/services/dev.ts | Wires Ctrl+C to resolve the background promise and adds an explicit process.exit(0) after the main await. |
| packages/theme/src/cli/services/dev.test.ts | Updates handler construction and adds a Ctrl+C test asserting onClose is called. |
| .changeset/fix-theme-dev-analytics.md | Declares a patch change and describes the user-visible behavior. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| }), | ||
| ]) | ||
|
|
||
| process.exit(0) |
There was a problem hiding this comment.
process.exit(0) here will terminate the process before ThemeCommand.run()'s finally { await this.logAnalyticsData(...) } executes and before any base-command post-run analytics hook can run, which likely reintroduces the “analytics not sent” issue and also skips the metafieldsPull() that runs after dev() returns in commands/theme/dev.ts. Instead of exiting the process here, let dev() return and ensure shutdown is achieved by closing the server/watchers/stdin raw mode so Node can exit naturally (or set process.exitCode = 0 after cleanup).
| readline.emitKeypressEvents(process.stdin) | ||
|
|
||
| const keypressHandler = createKeypressHandler(urls, ctx) | ||
| const keypressHandler = createKeypressHandler(urls, ctx, resolveBackgroundJob) |
There was a problem hiding this comment.
createKeypressHandler expects onClose: () => void, but resolveBackgroundJob from promiseWithResolvers<void>() is typed as (value: void | PromiseLike<void>) => void. With strictFunctionTypes enabled, passing resolveBackgroundJob directly is not type-compatible. Wrap it in a zero-arg function (e.g., call resolveBackgroundJob(undefined)) or change the resolver typing to accept an optional arg when T is void.
| const keypressHandler = createKeypressHandler(urls, ctx, resolveBackgroundJob) | |
| const keypressHandler = createKeypressHandler(urls, ctx, () => resolveBackgroundJob(undefined)) |
| '@shopify/theme': patch | ||
| --- | ||
|
|
||
| Fix analytics not being sent when exiting `theme dev` via Ctrl+C. The process now waits for the post-run analytics hook to complete before terminating. |
There was a problem hiding this comment.
The changeset text says the process "waits for the post-run analytics hook to complete before terminating", but the PR description/code path is explicitly “don’t wait for analytics” and currently calls process.exit(0) immediately after the main promise chain. Please update the changeset wording to match the actual behavior (or adjust the implementation to actually wait, if that’s the intent).
WHY are these changes introduced?
When users press Ctrl+C to exit
shopify theme dev, the process immediately callsprocess.exit(), terminating before the oclif post-run hook can send analytics events. This means we lose telemetry data for theme dev sessions.The
backgroundJobPromisewas originally typed asPromise<never>because it was only meant to reject on error (never resolve). This meant there was no mechanism to gracefully complete the promise chain on user-initiated exit.WHAT is this pull request doing?
Fixes analytics not being sent when exiting
theme devvia Ctrl+C by implementing graceful shutdown:process.exit()directlyprocess.exit(0)immediately (fire-and-forget for analytics)The post-run hook fires analytics asynchronously. We don't wait for it to complete—analytics is non-critical, and immediate exit provides better UX than blocking.
How to test your changes?
shopify theme devagainst a development storeChecklist
pnpm changeset add