Skip to content

fix: don't show trace when running hack up in an uninitialized project - #14

Merged
rhymiz merged 2 commits into
hack-dance:mainfrom
rhymiz:main
Feb 26, 2026
Merged

fix: don't show trace when running hack up in an uninitialized project#14
rhymiz merged 2 commits into
hack-dance:mainfrom
rhymiz:main

Conversation

@rhymiz

@rhymiz rhymiz commented Feb 26, 2026

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

Bug Fixes

  • Improved error messaging when running commands outside a project context with clearer, user-facing messages
  • Prevents internal error details and stack traces from appearing in user output

Tests

  • Added comprehensive test suite for the "up" command validating error handling for missing project contexts and unknown command flags

@changeset-bot

changeset-bot Bot commented Feb 26, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 081f358

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai

coderabbitai Bot commented Feb 26, 2026

Copy link
Copy Markdown

Walkthrough

The changes introduce a custom MissingProjectContextError class for explicit error handling when project context is unavailable. The handleUp command now catches this specific error to provide user-facing feedback without exposing internal error details. A comprehensive test suite validates the behavior for missing projects and invalid flags.

Changes

Cohort / File(s) Summary
Project Context Error Handling
src/commands/project.ts, tests/project-up-command.test.ts
Introduces MissingProjectContextError class and updates handleUp to catch and gracefully handle missing project context; adds test suite validating user-facing error messages and unknown flag handling with captured stdout/stderr output.

Sequence Diagram

sequenceDiagram
    participant CLI as CLI (runCli)
    participant Handler as handleUp
    participant Resolve as resolveProjectForArgs
    participant Require as requireProjectContext
    participant Error as MissingProjectContextError

    CLI->>Handler: invoke command
    Handler->>Resolve: call resolveProjectForArgs
    Resolve->>Require: call requireProjectContext
    alt Project context missing
        Require->>Error: throw MissingProjectContextError
        Error-->>Handler: propagate error
        Handler->>Handler: catch MissingProjectContextError
        Handler->>Handler: log user-facing message
        Handler-->>CLI: return exit code 1
    else Project context found
        Require-->>Resolve: return context
        Resolve-->>Handler: return resolved project
        Handler-->>CLI: continue execution
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 Twitching whiskers with delight,
Errors handled, crisp and right!
MissingProject warns with grace,
No stack traces show their face.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding proper error handling to prevent stack traces when running 'hack up' in a project without initialization.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
tests/project-up-command.test.ts (1)

6-10: Consider using interface for object shapes.

Per coding guidelines, prefer interface over type for defining object shapes.

♻️ Proposed change
-type CapturedRunResult = {
+interface CapturedRunResult {
   readonly exitCode: number;
   readonly stdout: string;
   readonly stderr: string;
-};
+}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/project-up-command.test.ts` around lines 6 - 10, Replace the type alias
with an interface: change the declaration "type CapturedRunResult = { readonly
exitCode: number; readonly stdout: string; readonly stderr: string; }" to
"interface CapturedRunResult { readonly exitCode: number; readonly stdout:
string; readonly stderr: string; }" so the object shape uses interface
semantics; keep the property names and readonly modifiers unchanged and update
any imports/uses that reference CapturedRunResult if necessary.
src/commands/project.ts (1)

4126-4139: Consider applying the same error handling to other command handlers.

Only handleUp catches MissingProjectContextError gracefully. The same stack trace issue would occur for hack down, hack restart, hack ps, hack run, hack logs, and hack open when run in an uninitialized project.

If consistent UX is desired, the same try-catch pattern could be applied to the other handlers, or the error handling could be centralized in resolveProjectForArgs.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/commands/project.ts` around lines 4126 - 4139, The project resolution
code currently catches MissingProjectContextError in the handleUp flow but not
elsewhere; update the other command handlers that call resolveProjectForArgs
(e.g., handleDown, handleRestart, handlePs, handleRun, handleLogs, handleOpen)
to wrap their resolveProjectForArgs call in the same try/catch that checks for
MissingProjectContextError and logs via logger.error({ message: error.message })
and returns 1, or alternatively modify resolveProjectForArgs itself to return a
well-known result type or throw a wrapped error that callers can uniformly
handle; use the existing symbols resolveProjectForArgs,
MissingProjectContextError, and logger.error to implement the consistent
handling.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/project-up-command.test.ts`:
- Around line 29-38: The cleanup block incorrectly restores environment vars by
assigning undefined (which becomes the string "undefined"); change logic in the
teardown to delete the env keys when the originals were undefined: for the
HACK_SETUP_SYNC_MODE handling in the test (originalSetupSyncMode /
process.env.HACK_SETUP_SYNC_MODE) and for HACK_LOGGER handling (originalLogger /
process.env.HACK_LOGGER) set the env variable to the original value when
defined, otherwise use the delete operator to remove the key (delete
process.env.HACK_SETUP_SYNC_MODE and delete process.env.HACK_LOGGER).

---

Nitpick comments:
In `@src/commands/project.ts`:
- Around line 4126-4139: The project resolution code currently catches
MissingProjectContextError in the handleUp flow but not elsewhere; update the
other command handlers that call resolveProjectForArgs (e.g., handleDown,
handleRestart, handlePs, handleRun, handleLogs, handleOpen) to wrap their
resolveProjectForArgs call in the same try/catch that checks for
MissingProjectContextError and logs via logger.error({ message: error.message })
and returns 1, or alternatively modify resolveProjectForArgs itself to return a
well-known result type or throw a wrapped error that callers can uniformly
handle; use the existing symbols resolveProjectForArgs,
MissingProjectContextError, and logger.error to implement the consistent
handling.

In `@tests/project-up-command.test.ts`:
- Around line 6-10: Replace the type alias with an interface: change the
declaration "type CapturedRunResult = { readonly exitCode: number; readonly
stdout: string; readonly stderr: string; }" to "interface CapturedRunResult {
readonly exitCode: number; readonly stdout: string; readonly stderr: string; }"
so the object shape uses interface semantics; keep the property names and
readonly modifiers unchanged and update any imports/uses that reference
CapturedRunResult if necessary.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 78f3590 and 081f358.

📒 Files selected for processing (2)
  • src/commands/project.ts
  • tests/project-up-command.test.ts

Comment on lines +29 to +38
if (originalSetupSyncMode !== undefined) {
process.env.HACK_SETUP_SYNC_MODE = originalSetupSyncMode;
} else {
process.env.HACK_SETUP_SYNC_MODE = undefined;
}
if (originalLogger !== undefined) {
process.env.HACK_LOGGER = originalLogger;
} else {
process.env.HACK_LOGGER = undefined;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Bug: Setting env var to undefined doesn't delete it.

In Node.js/Bun, process.env.VAR = undefined coerces undefined to the string "undefined" rather than removing the variable. Use delete to properly restore the original state.

🐛 Proposed fix
   if (originalSetupSyncMode !== undefined) {
     process.env.HACK_SETUP_SYNC_MODE = originalSetupSyncMode;
   } else {
-    process.env.HACK_SETUP_SYNC_MODE = undefined;
+    delete process.env.HACK_SETUP_SYNC_MODE;
   }
   if (originalLogger !== undefined) {
     process.env.HACK_LOGGER = originalLogger;
   } else {
-    process.env.HACK_LOGGER = undefined;
+    delete process.env.HACK_LOGGER;
   }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (originalSetupSyncMode !== undefined) {
process.env.HACK_SETUP_SYNC_MODE = originalSetupSyncMode;
} else {
process.env.HACK_SETUP_SYNC_MODE = undefined;
}
if (originalLogger !== undefined) {
process.env.HACK_LOGGER = originalLogger;
} else {
process.env.HACK_LOGGER = undefined;
}
if (originalSetupSyncMode !== undefined) {
process.env.HACK_SETUP_SYNC_MODE = originalSetupSyncMode;
} else {
delete process.env.HACK_SETUP_SYNC_MODE;
}
if (originalLogger !== undefined) {
process.env.HACK_LOGGER = originalLogger;
} else {
delete process.env.HACK_LOGGER;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/project-up-command.test.ts` around lines 29 - 38, The cleanup block
incorrectly restores environment vars by assigning undefined (which becomes the
string "undefined"); change logic in the teardown to delete the env keys when
the originals were undefined: for the HACK_SETUP_SYNC_MODE handling in the test
(originalSetupSyncMode / process.env.HACK_SETUP_SYNC_MODE) and for HACK_LOGGER
handling (originalLogger / process.env.HACK_LOGGER) set the env variable to the
original value when defined, otherwise use the delete operator to remove the key
(delete process.env.HACK_SETUP_SYNC_MODE and delete process.env.HACK_LOGGER).

@roodboi roodboi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@rhymiz
rhymiz merged commit 7e2d37f into hack-dance:main Feb 26, 2026
4 checks passed
roodboi pushed a commit that referenced this pull request Feb 26, 2026
## <small>1.13.2 (2026-02-26)</small>

* Merge pull request #1 from rhymiz/codex/fix-up-missing-hack-stack ([081f358](081f358)), closes [#1](#1)
* Merge pull request #14 from rhymiz/main ([7e2d37f](7e2d37f)), closes [#14](#14)
* fix(project): suppress missing .hack stack trace for hack up ([ced1f59](ced1f59))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants