Skip to content

feat(providers): add recovery category taxonomy for provider error normalization#399

Open
mmmself wants to merge 1 commit into
OpenCoworkAI:mainfrom
mmmself:fix/212-provider-error-recovery
Open

feat(providers): add recovery category taxonomy for provider error normalization#399
mmmself wants to merge 1 commit into
OpenCoworkAI:mainfrom
mmmself:fix/212-provider-error-recovery

Conversation

@mmmself

@mmmself mmmself commented Jul 5, 2026

Copy link
Copy Markdown

Summary

Implements #212 — adds a recovery category taxonomy to provider error normalization so the UI can show targeted, actionable recovery hints instead of generic "something went wrong" messages.

What was added

packages/providers/src/errors.ts (core):

  • RecoveryCategory type — 16 categories + unknown fallback
  • classifyRecoveryCategory(status, code, message, wire) — classifies errors by priority: HTTP status > message patterns > system code > fallback
  • recoveryHintFor(category) — returns per-category human-readable recovery text
  • NormalizedProviderError extended with recovery_category field
  • normalizeProviderError now computes the recovery category

Data flow:

retry.ts → normalizeProviderError() computes recovery_category (logging)
generate.ts → normalizeGenerationFailure() tags upstream_recovery_category (IPC)
renderer → extractUpstreamContext / deriveGenerateHypothesis
         → DiagnosticHypothesis.recoveryCategory
         → buildGenerateErrorDescription() shows in toast

Files changed: 6 files, +243/-8

Verification

  • biome check passes with 0 errors, 0 warnings

…rmalization

- Add RecoveryCategory type (16 categories + unknown fallback)
- Add classifyRecoveryCategory(status, code, message, wire) for error taxonomy
- Add recoveryHintFor(category) returning per-category actionable hints
- Extend NormalizedProviderError with recovery_category field
- Tag upstream_recovery_category on IPC-bound error objects via normalizeGenerationFailure
- Add extractUpstreamSystemCode helper for network error detection
- Add recoveryCategory to DiagnosticHypothesis in shared diagnostics
- Surface recovery category in renderer toast via buildGenerateErrorDescription
- Thread wire param through normalizeProviderError → retry layer
@github-actions github-actions Bot added area:desktop apps/desktop (Electron shell, renderer) area:providers packages/providers (pi-ai adapter, model calls) labels Jul 5, 2026

@github-actions github-actions Bot 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.

Review mode: initial

Findings

  • [Minor] classifyRecoveryCategory priority comment does not match implementation — the docstring says "Priority: status code > message patterns > network/system code > fallback" but the code checks system code before status (packages/providers/src/errors.ts:220-226). This is a documentation inconsistency that could confuse future maintainers. Update the comment to reflect actual ordering (system code > status > message patterns).

    Suggested fix: Change the comment to Priority: network/system code > status code > message patterns > fallback.

  • [Minor] No unit tests added for the new recovery classification logic. classifyRecoveryCategory, recoveryHintFor, extractUpstreamSystemCode, and the updated buildGenerateErrorDescription have no Vitest coverage. Per CLAUDE.md: "New features require at least one Vitest test." At minimum, add tests for classifyRecoveryCategory covering the major categories (auth, network, rate-limit, gateway, unknown) and for buildGenerateErrorDescription verifying that recoveryCategory appears in the output when present.

    Suggested fix: Add Vitest tests in packages/providers/src/errors.test.ts and apps/desktop/src/renderer/src/store/slices/errors.test.ts.

  • [Minor] The buildGenerateErrorDescription function appends a non-i18n "Recovery: " string derived from the recoveryCategory enum value (apps/desktop/src/renderer/src/store/slices/errors.ts:248-256). This is English-only and not passed through the tr() i18n layer. While recoveryHintFor provides English hints for programmatic use, the toast display should eventually use i18n keys. Consider adding an i18n key or deferring to a future i18n pass.

    Suggested fix: Either use recoveryHintFor() and pass through i18n, or mark with a TODO(i18n) comment.

  • [Major] Linked issue #212 is claimed as "Implements" but the issue content is not accessible in the public repository to verify acceptance criteria against the diff. From the PR description, the changes appear to match: adding a RecoveryCategory taxonomy and flowing it through normalizeProviderError → IPC → renderer store → toast. However, without seeing the issue's stated requirements, completeness cannot be confirmed. If the issue has additional acceptance criteria (e.g., UI test, specific recovery hints), this PR may be partial.

    Suggested fix: The author should verify that the issue's acceptance criteria are fully met, or change the PR body from "Implements #212" to "Refs #212" and open follow-up issues for any remaining scope. Maintainers should inspect the issue before merging.

Summary

This PR adds a structured recovery category taxonomy to provider error normalization. The core logic lives in packages/providers/src/errors.ts with new exports RecoveryCategory, classifyRecoveryCategory, and recoveryHintFor. It flows through normalizeGenerationFailure in apps/desktop/src/main/ipc/generate.ts and the renderer-side error handling in errors.ts. The implementation is directionally sound and follows project patterns. No license or dependency issues. The main gaps are missing test coverage and the linked issue completeness validation.

Testing

  • Not run (automation). Recommend adding Vitest unit tests for classifyRecoveryCategory (all 16 categories + unknown), recoveryHintFor, extractUpstreamSystemCode, and the updated buildGenerateErrorDescription.

Open-CoDesign Bot

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

Labels

area:desktop apps/desktop (Electron shell, renderer) area:providers packages/providers (pi-ai adapter, model calls)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant