docs(errors): record typed-error adoption in the contracts reference - #542
Conversation
Splits lib/request/fetch-helpers.ts (1,497 lines) into four focused modules, moving code verbatim: - token-refresh.ts (147 lines): shouldRefreshToken, refreshAndUpdateToken, plus private CodexAuthSetter, isRetryableRefreshFailure, isRetryableAuthSetterError - error-classification.ts (366 lines): isEntitlementError, isWorkspaceDisabledError, createEntitlementErrorResponse, the unsupported-Codex-model detection/fallback chain and its private helpers (canonicalizeModelName, normalizeFallbackChain, patterns) - url-rewriting.ts (199 lines): extractRequestUrl, rewriteUrlForCodex, proxy resolution (resolveProxyUrlForRequest, applyProxyCompatibleInit, closeSharedProxyDispatchers) and the shared dispatcher cache - headers.ts (99 lines): createCodexHeaders (all overloads) and the RFC 8594 deprecation/sunset header logging fetch-helpers.ts (now 756 lines) remains the re-export facade for every previously-exported symbol, so no importer changes anywhere. Response handling (handleErrorResponse/handleSuccessResponse), rate-limit parsing, and transformRequestForCodex stay in fetch-helpers.ts as they do not fit a seam cleanly. Runtime export surface verified identical before/after; no import cycles introduced. Zero behavior change. Audit roadmap §4.1.2. https://claude.ai/code/session_01XNtnkLbBiXZxfQQYLMpucB
Review follow-up: the three symbols that gained export during the split (CHATGPT_CODEX_UNSUPPORTED_MODEL_CODE, isUnsupportedCodexModelForChatGpt, logDeprecationHeaders) exist only for sibling lib/request modules; the facade in fetch-helpers.ts deliberately does not re-export them. https://claude.ai/code/session_01XNtnkLbBiXZxfQQYLMpucB
Audit roadmap §4.3 (request layer); stacked on the fetch-helpers split (PR #524). Inventory result: the request layer is ALREADY fully adopted in code, so this commit is documentation-only — no throw sites changed. Sites already using typed contracts (verified, unchanged): - lib/request/token-refresh.ts:103,112,133 — CodexAuthError (ERROR_MESSAGES.TOKEN_REFRESH_FAILED) with retryable/context/cause; catch sites verified: lib/refresh-guardian.ts:178 uses `instanceof CodexAuthError && !error.retryable`, which holds; test/fetch-helpers.test.ts asserts the exact message and retryable flags. - lib/request/fetch-helpers.ts:212 — intentional rethrow of an error originating in request-transformer.ts (out of scope); left unchanged. Sites left as-is, with reasons: - lib/request/headers.ts:67 — `TypeError: createCodexHeaders requires accountId and accessToken`. The Options-Object Compatibility Contract documents no CodexError subclass for argument misuse, and the native TypeError is a deliberate convention shared with the five other dual-call helpers (parallel-probe, rotation, request-transformer, rate-limit-backoff — all outside this PR's scope). Converting only this site would fracture the convention and change `instanceof TypeError` identity. Tests assert the exact message (test/fetch-helpers.test.ts:614,1834,1843). - lib/request/error-classification.ts / fetch-helpers.ts error mapping — the HTTP/Error Mapping Contract returns normalized Response payloads (stable error.message/error.code), not thrown errors; typed Error classes intentionally do not apply. - lib/request/url-rewriting.ts — no throw sites (native TypeError from the URL constructor is platform behavior asserted by tests). New classes: none needed; lib/errors.ts already defines every shape the documented contracts require. Doc change: docs/reference/error-contracts.md now references the machine-readable types backing the contracts — a "Typed Errors" subsection under the Fetch Helpers contract (CodexAuthError code, message, retryable/cause/context semantics, catch-site guidance) and a note in the Options-Object Compatibility Contract pinning the native TypeError convention for invalid named-parameter calls. Verification: typecheck clean; fetch-helpers, quota-probe, index, index-retry, public-api-contract, chaos/fault-injection, documentation, errors suites: 419/419 passed, identical to base (origin/claude/audit-06-fetch-helpers-split) via git stash comparison. https://claude.ai/code/session_01XNtnkLbBiXZxfQQYLMpucB
|
Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits. |
|
Warning Review limit reached
More reviews will be available in 3 minutes and 10 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (6)
✨ Finishing Touches🧪 Generate unit tests (beta)
✨ Simplify code
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. Comment |
…very log The request layer already adopts the typed error contracts; PR #542 is the verification record. Proxy/config layers remain to be re-checked after their refactor stacks merge. https://claude.ai/code/session_01XNtnkLbBiXZxfQQYLMpucB
Review follow-up: documents that the passed Auth is mutated in place after the persistence await, that queuedRefresh serializes same-account refreshes (so concurrent calls coalesce rather than race), and the remaining caller invariants around shared references. https://claude.ai/code/session_01XNtnkLbBiXZxfQQYLMpucB
Summary
Closes out audit roadmap §4.3 for the request layer (
docs/audits/AUDIT_2026-06-10.md, PR #522) — with an honest result: the code portion is stale; the request layer already fully adopts the typed error contracts. This PR is the verification record plus the documentation the contract reference was missing.What the verification found (no code changes needed)
lib/errors.tsalready provides the full taxonomy (CodexErrorbase,CodexApiError,CodexAuthError,CodexNetworkError,CodexRateLimitError,StorageError,CodexUnavailableError+ guard).token-refresh.tsalready throwsCodexAuthErrorwithretryable/cause/contextat all three failure sites; the catch site (refresh-guardian.ts) relies oninstanceof CodexAuthError && !retryable— verified intact.Responsepayloads (stableerror.message/error.code), not thrown errors — typed classes deliberately don't apply there.TypeError(createCodexHeadersargument misuse) is a deliberate convention shared by all six dual-call helpers across the codebase, pinned by tests; converting one in isolation would fracture it.Changes (docs only)
docs/reference/error-contracts.md(+10 lines): a "Typed Errors" subsection under the Fetch Helpers contract (documentsCodexAuthError, itsCODEX_AUTH_ERRORcode, exact message,retryable/cause/contextsemantics, and that HTTP errors surface as Responses, not throws), and a note pinning the native-TypeError convention in the Options-Object Compatibility Contract.Validation
npm run typecheckRisk / Rollback
Docs-only; revert the single commit.
https://claude.ai/code/session_01XNtnkLbBiXZxfQQYLMpucB
Generated by Claude Code
note: greptile review for oc-chatgpt-multi-auth. cite files like
lib/foo.ts:123. confirm regression tests + windows concurrency/token redaction coverage.Greptile Summary
this pr closes audit §4.3 by verifying that the request layer already fully uses the typed error hierarchy, then adding the missing reference documentation to
docs/reference/error-contracts.md. no runtime behaviour changes.CodexAuthErrorthrow semantics,retryable/cause/contextfields, and why http errors surface asResponseobjects instead of thrown errors.TypeErrorconvention for invalid named-parameter calls across the six dual-call helpers.Confidence Score: 5/5
docs-only change; every claim in the new sections is verified against the live code, and no runtime paths are altered
the new documentation is factually accurate: error message matches the constant, code matches ErrorCode.AUTH_ERROR, retryable logic is correctly described for all three throw sites, cause/context mutually-exclusive presence is correctly qualified as 'where available', and the TypeError message in headers.ts matches the pinned example exactly
no files require special attention
Important Files Changed
Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart TD A[refreshAndUpdateToken called] --> B{authSetter present?} B -- no --> E1[throw CodexAuthError\nretryable: false\nno cause, no context] B -- yes --> C[queuedRefresh token] C --> D{result.type} D -- failed --> E2[throw CodexAuthError\nretryable: isRetryableRefreshFailure\ncontext: refreshFailureReason + statusCode] D -- success --> F[authSetter.set persist] F -- throws --> E3[throw CodexAuthError\nretryable: isRetryableAuthSetterError\ncause: error] F -- ok --> G[mutate currentAuth in-place\nreturn currentAuth] style E1 fill:#f66,color:#fff style E2 fill:#f66,color:#fff style E3 fill:#f66,color:#fff style G fill:#6a6,color:#fffReviews (2): Last reviewed commit: "docs(request): pin refreshAndUpdateToken..." | Re-trigger Greptile