Skip to content

fix: centralize error handling with CliError and global handler#144

Merged
scottlovegrove merged 2 commits intomainfrom
scottl/errors
Apr 5, 2026
Merged

fix: centralize error handling with CliError and global handler#144
scottlovegrove merged 2 commits intomainfrom
scottl/errors

Conversation

@scottlovegrove
Copy link
Copy Markdown
Collaborator

Summary

  • Introduces CliError class (src/lib/errors.ts) with typed error codes, optional hints, and an error/info type for controlling output color
  • Adds a global error handler in src/index.ts that formats all unhandled errors as structured JSON ({"error":{"code","message","hints"}}) when --json is passed, or as formatted text otherwise
  • Migrates all ~47 source files from inconsistent throw new Error(), console.error() + process.exit(1), and console.error() + process.exitCode = 1 patterns to throw new CliError(code, message, hints?)
  • Adds NoTokenError subclass (type info, renders yellow) for the "not authenticated" case
  • Zero process.exit(1) calls remain in the source

Test plan

  • npm run type-check passes
  • npm run lint:check passes
  • All 387 tests pass (25 tests updated to assert on CliError.code instead of console output)
  • tw thread view invalid-ref shows formatted error text
  • tw thread view invalid-ref --json shows {"error":{"code":"INVALID_REF","message":"..."}}
  • tw auth status when unauthenticated shows yellow info-style error
  • tw auth status --json when unauthenticated shows structured JSON error

🤖 Generated with Claude Code

Introduce a CliError class with typed error codes and a global error
handler in index.ts that formats errors as structured JSON when --json
is passed. This replaces the inconsistent mix of throw new Error(),
console.error + process.exit(1), and console.error + process.exitCode
patterns across ~47 files.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@doistbot doistbot requested a review from pauloslund April 5, 2026 20:46
@scottlovegrove scottlovegrove self-assigned this Apr 5, 2026
@scottlovegrove scottlovegrove added the 👀 Show PR PR must be reviewed before or after merging label Apr 5, 2026
Copy link
Copy Markdown
Member

@doistbot doistbot left a comment

Choose a reason for hiding this comment

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

This PR is a fantastic refactoring effort that centralizes error handling and standardizes on CliError to significantly enhance the CLI's maintainability and output reliability. The unified global handler successfully eliminates inconsistent exit patterns and improves the overall experience for both text and JSON outputs. A few minor areas were noted for refinement, specifically regarding the preservation of stack traces for unexpected runtime errors, consistently applying NoTokenError across all unauthenticated paths, handling raw 401 errors gracefully in the status command, and adding missing codes to the ErrorCode union.

Share FeedbackReview Logs

- Preserve stack traces for unexpected (non-CliError) errors in text mode
- Use NoTokenError consistently on all no-token paths in getApiToken
- Catch NoTokenError and 401s in auth status to normalize auth errors
- Add UNKNOWN_AGENT to ErrorCode union

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@scottlovegrove scottlovegrove merged commit b1ef8d3 into main Apr 5, 2026
4 checks passed
@scottlovegrove scottlovegrove deleted the scottl/errors branch April 5, 2026 21:03
doist-release-bot bot added a commit that referenced this pull request Apr 5, 2026
## [2.23.2](v2.23.1...v2.23.2) (2026-04-05)

### Bug Fixes

* centralize error handling with CliError and global handler ([#144](#144)) ([b1ef8d3](b1ef8d3))
@doist-release-bot
Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 2.23.2 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

released 👀 Show PR PR must be reviewed before or after merging

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants