Skip to content

feat(cli-v2): add well-known CLI error template registry#16043

Open
iamnamananand996 wants to merge 2 commits into
devin/1779374495-cli-v2-error-rendererfrom
devin/1779375852-cli-v2-well-known-errors
Open

feat(cli-v2): add well-known CLI error template registry#16043
iamnamananand996 wants to merge 2 commits into
devin/1779374495-cli-v2-error-rendererfrom
devin/1779375852-cli-v2-well-known-errors

Conversation

@iamnamananand996
Copy link
Copy Markdown
Contributor

Description

Linear ticket: Refs FER-10016

Wave-2 R14 of the cli-v2 error UX/DX cleanup: introduces a registry of well-known CLI error templates, modeled on the existing MdxErrorCode pattern that the docs MDX parser uses.

Stacked on #16040 (wave-1 renderer + --debug). Re-target to main after #16040 merges. Independent of #16041 (R5) and #16042 (R13).

Why

Today, ~60 cli-v2 files each call throw new CliError({ message, code }) with their own ad-hoc message. There is no shared catalog of "the well-known ways the Fern CLI can fail", so identical failure modes get inconsistent wording, hints, and docs links across commands. Adding a new typed error requires hand-writing the message, hint, and docsLink at every call site.

What

A new FernCliErrors registry at packages/cli/cli-v2/src/errors/wellKnown/CliErrors.ts. Each entry is a tiny factory that returns a fully-formed CliError — fixed code, templated message, actionable hint, and (where appropriate) a docs link. Adding a new well-known failure becomes a 5-line PR (template + test + call-site swap), and every consumer of that template gets identical UX automatically.

Initial templates:

Template Code Use case
AuthRequired AUTH_ERROR User must log in (accepts optional message override)
Unauthorized AUTH_ERROR Token rejected by server
FernYmlNotFound CONFIG_ERROR No fern.yml in cwd or ancestors
FlagsMutex CONFIG_ERROR Two flags passed that can't be combined
FlagRequires CONFIG_ERROR Flag depends on another flag being set
MissingRequiredFlags CONFIG_ERROR Required flag(s) not provided
FileNotFound CONFIG_ERROR User-supplied path doesn't exist
UnsupportedValue CONFIG_ERROR Value not in supported enum
HttpFetchFailed NETWORK_ERROR Non-2xx response from a URL fetch
EmptyStdin CONFIG_ERROR --api - but nothing piped in
ValidationFailed VALIDATION_ERROR Caller already printed violations
InternalError INTERNAL_ERROR Unreachable state — links to bug-report flow

Changes Made

  • New packages/cli/cli-v2/src/errors/wellKnown/CliErrors.ts with the 12 templates above.
  • Migrated representative call sites:
    • sdk generate — 4 flag mutex/requires checks
    • sdk add — fern.yml missing, missing required flag, duplicate target (now with hint), unsupported language
    • auth whoami — auth-required path
    • ApiSpecResolver — empty stdin, missing file, HTTP fetch failure
  • New packages/cli/cli-v2/src/__test__/wellKnownErrors.test.ts with 14 unit tests covering every template + a smoke test that every entry returns a non-empty hint or docs link.
  • Unreleased changelog: packages/cli/cli/changes/unreleased/cli-v2-well-known-errors.yml (feat).
  • Updated README.md generator — N/A; user-facing reference for these codes lands in R15.

Testing

  • Unit tests added/updated — 14 new tests in wellKnownErrors.test.ts. Full cli-v2 suite (728 tests) green.
  • Manual testing completed — pnpm format, pnpm lint:biome, pnpm check, pnpm turbo run compile --filter @fern-api/cli-v2 all clean.

Future work

  • More call sites will migrate incrementally — the migrated sites here are intentionally a small representative set so the pattern is reviewable. R15 will list every error[CODE] in user-facing docs.

Link to Devin session: https://app.devin.ai/sessions/c00fe336eaa44387a47db9083451e93c
Requested by: @iamnamananand996

Introduces a registry of named CLI error templates at `packages/cli/cli-v2/src/errors/wellKnown/CliErrors.ts`, mirroring the `MdxErrorCode` pattern for the rest of the CLI.

Each template is a tiny factory returning a `CliError` with a fixed code, a templated message, an actionable hint, and (where appropriate) a docs link. Adding a new well-known failure becomes a 5-line PR (template + test + call-site swap), and every consumer gets identical UX automatically.

Initial templates:
- `AuthRequired` (with optional message override)
- `Unauthorized`
- `FernYmlNotFound`
- `FlagsMutex`
- `FlagRequires`
- `MissingRequiredFlags`
- `FileNotFound`
- `UnsupportedValue`
- `HttpFetchFailed`
- `EmptyStdin`
- `ValidationFailed`
- `InternalError`

Migrates representative call sites in:
- `sdk generate` (4 mutex/requires flag checks)
- `sdk add` (4 sites: fern.yml missing, missing flag, duplicate target, unsupported language)
- `auth whoami` (auth-required path)
- `ApiSpecResolver` (3 sites: empty stdin, missing file, HTTP fetch failure)

14 new unit tests cover every template plus a smoke test that every entry returns a non-empty hint or docs link.
@devin-ai-integration
Copy link
Copy Markdown
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

@iamnamananand996 iamnamananand996 marked this pull request as ready for review May 21, 2026 15:12
Copy link
Copy Markdown

@claude claude Bot left a comment

Choose a reason for hiding this comment

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

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.

Tip: disable this comment in your organization's Code Review settings.

Update CliErrors and tests to improve hints and formatting: change supported wording to "Supported <what> values", ensure HttpFetchFailed omits an extra space when statusText is empty, and update tests to expect these hints and message formatting. Fix whoami command to return after writing JSON when --json is used (avoid throwing an auth error after emitting JSON). Also remove the trailing `as const` from the exported FernCliErrors object.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants