Skip to content

Commit a52ccab

Browse files
committed
Merge pull request #542 from ndycode/claude/audit-24-error-contracts-request
docs(errors): record typed-error adoption in the contracts reference
2 parents ff7f7ba + 4c0e0b7 commit a52ccab

2 files changed

Lines changed: 20 additions & 0 deletions

File tree

docs/reference/error-contracts.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,14 @@ Compatibility guarantees:
6262
- Error responses are normalized to JSON error payloads with a stable `error.message` field.
6363
- Diagnostics may include request/correlation IDs when available.
6464

65+
### Typed Errors
66+
67+
The request layer's thrown errors are backed by the typed hierarchy in `lib/errors.ts` (base class `CodexError`, which extends `Error` and carries a stable `code` string):
68+
69+
- `refreshAndUpdateToken` throws `CodexAuthError` (`code: "CODEX_AUTH_ERROR"`) with the message `Failed to refresh token, authentication required` on any refresh failure. The error carries a `retryable` boolean (transient network/lock failures are retryable; invalid-grant style failures are not) and, where available, `cause` and `context` (`refreshFailureReason`, `statusCode`).
70+
- Catch sites may rely on `instanceof CodexAuthError` (or the structural `code` property) plus `retryable` to decide whether to re-attempt or force re-authentication.
71+
- HTTP error responses are returned as normalized `Response` payloads (see above), not thrown, so they intentionally have no `Error` class.
72+
6573
---
6674

6775
## Runtime Rotation Proxy Error Contract
@@ -94,6 +102,8 @@ Supported dual-call forms include:
94102
- `getRateLimitBackoffWithReason(...)` and `getRateLimitBackoffWithReason({ ... })`
95103
- `transformRequestBody(...)` and `transformRequestBody({ ... })`
96104

105+
Invalid named-parameter calls (missing or wrongly typed required fields, or unknown keys) throw a native `TypeError` with a `<helper> requires ...` message — for example, `createCodexHeaders` throws `TypeError: createCodexHeaders requires accountId and accessToken`. This is a deliberate, shared convention across the dual-call helpers and is not wrapped in a `CodexError` subclass.
106+
97107
---
98108

99109
## Related

lib/request/token-refresh.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,16 @@ function isRetryableAuthSetterError(error: unknown): boolean {
9090

9191
/**
9292
* Refreshes the OAuth token and updates stored credentials
93+
*
94+
* Mutation contract: on success the passed `currentAuth` object is updated
95+
* IN PLACE (access/refresh/expires) after the persistence await, and the same
96+
* reference is returned. Same-account refreshes are serialized by
97+
* `queuedRefresh`, so two concurrent calls for one account coalesce rather
98+
* than race; callers must still not share one Auth object across calls for
99+
* DIFFERENT accounts, and must not read token fields from a shared reference
100+
* while a refresh for it is in flight (the window between the persistence
101+
* await and the mutation block exposes the pre-refresh values).
102+
*
93103
* @param currentAuth - Current auth state
94104
* @param client - Codex client for updating stored credentials
95105
* @returns Updated auth (throws on failure)

0 commit comments

Comments
 (0)