fix(cli): gracefully handle docs resolution failures in missing-redirects rule#15905
fix(cli): gracefully handle docs resolution failures in missing-redirects rule#15905paarthfern wants to merge 2 commits into
Conversation
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
There was a problem hiding this comment.
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.
| case "resolve-failed": | ||
| return { | ||
| file: () => [ | ||
| { | ||
| severity: "warning", | ||
| message: | ||
| `Missing redirects check skipped: failed to resolve docs definition (${fetchResult.reason}). ` + | ||
| "This can happen after a major CLI upgrade that changes type naming. " + | ||
| "Publish your docs once to update the baseline, then re-run this check." | ||
| } | ||
| ] | ||
| }; |
There was a problem hiding this comment.
🟡 Switch on discriminated union FetchResult lacks default: assertNever() for exhaustiveness
The makeSkipVisitor function switches on fetchResult.type (a discriminated union) but does not include a default case calling assertNever. Per CLAUDE.md: "Every switch statement on a discriminated union's type field must include a default case [that] call[s] assertNever from @fern-api/core-utils." The same package already follows this pattern in validateDocsWorkspace.ts:31-32. While TypeScript's return-type checking provides partial safety here, a new variant added to FetchResult without updating makeSkipVisitor would not produce a compile error in the default branch — only a potentially confusing implicit-undefined-return error.
| case "resolve-failed": | |
| return { | |
| file: () => [ | |
| { | |
| severity: "warning", | |
| message: | |
| `Missing redirects check skipped: failed to resolve docs definition (${fetchResult.reason}). ` + | |
| "This can happen after a major CLI upgrade that changes type naming. " + | |
| "Publish your docs once to update the baseline, then re-run this check." | |
| } | |
| ] | |
| }; | |
| case "resolve-failed": | |
| return { | |
| file: () => [ | |
| { | |
| severity: "warning", | |
| message: | |
| `Missing redirects check skipped: failed to resolve docs definition (${fetchResult.reason}). ` + | |
| "This can happen after a major CLI upgrade that changes type naming. " + | |
| "Publish your docs once to update the baseline, then re-run this check." | |
| } | |
| ] | |
| }; | |
| default: | |
| assertNever(fetchResult); |
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
Good catch — added default: assertNever(fetchResult) and the assertNever import in 789f56e.
…ects rule The missing-redirects rule called DocsDefinitionResolver.resolve() without error handling. When resolution failed (e.g. after a major CLI upgrade that changes inline type naming), the thrown TaskAbortSignal propagated as a fatal violation with an uninformative error message. Wrap the resolution and navigation-building code in a try-catch so the rule gracefully skips with a descriptive warning instead of crashing. Co-Authored-By: paarth <paarth@buildwithfern.com>
Co-Authored-By: paarth <paarth@buildwithfern.com>
789f56e to
00ae45f
Compare
Description
Follow-up to #15853 which added the core try-catch fix for the missing-redirects rule. This PR adds the
assertNeverexhaustiveness guard to themakeSkipVisitorswitch statement per CLAUDE.md conventions, and includes a changelog entry.Changes Made
default: assertNever(fetchResult)to themakeSkipVisitorswitch on theFetchResultdiscriminated union, ensuring compile-time safety when new variants are addedassertNeverimport from@fern-api/core-utilsTesting
@fern-api/docs-validatorpasspnpm lint:biomepassespnpm formatpassesLink to Devin session: https://app.devin.ai/sessions/9e60e54a91c84401a1d139ae7e2fb655
Requested by: @paarthfern