Errors, retries, and timeouts
Purpose and Scope
This page helps application developers understand how the OpenAI TypeScript and JavaScript SDK surfaces failed requests, how to configure diagnostic logging, and where retry and timeout behavior fits in the client lifecycle. The SDK is a generated OpenAI REST API client, so most failures originate from HTTP responses, transport failures, authentication configuration, aborts, or request construction. The README establishes the normal path: instantiate an OpenAI client, usually with an API key from the environment, call a resource method such as the Responses API, and read the typed result. Error handling starts by wrapping that same call boundary in application-level recovery code.
Sources: README.md, src/client.ts
OpenAI platform errors should be read together with SDK errors. The official error-code guidance describes common API status classes, including invalid authentication and incorrect API key cases, and recommends checking the key and organization context. In this SDK, the practical troubleshooting workflow is to verify client construction first, then inspect the thrown error, then enable logs only when needed. That order matters because a missing key, wrong base URL, removed header, or aborted request can all look like a generic failed request until the request options and response metadata are examined together.
Sources: README.md, tests/index.test.ts
Relevant Source Files
- README.md - Introduces the generated SDK, the default API-key environment variable pattern, and the primary request examples that define where errors are normally caught.
- src/client.ts - Contains the generated client entry point imports for request options, error helpers, retry timing support, platform headers, logging types, and API resource wiring.
- tests/index.test.ts - Exercises client construction, default header merging and removal, logging level behavior, and API promise logging signals.
- tests/log.test.ts - Verifies debug logging behavior, redaction of authorization headers, and non-mutation of user-provided header objects during logging.
Error Surfaces and Request Boundaries
The most important boundary is the awaited SDK method call. A call such as creating a response or chat completion returns a promise that either resolves to a typed response object or rejects. The README’s examples show the regular construction path with an OpenAI client and an API key read from the process environment; when that setup is wrong, the failure is observed at the same awaited call site. For robust applications, keep request construction, call execution, and result handling close enough that you can attach context such as the model, feature name, user operation, and retry policy without logging secrets.
Sources: README.md
The generated client imports its core error module and specific authentication-related error classes, including OAuth and subject-token provider errors. It also imports helper functions for converting unknown values into errors and detecting abort errors. Those imports show the client is designed to normalize different failure modes rather than leaving callers with only raw fetch exceptions. In practice, catch broadly at service boundaries, then branch on SDK error classes or structured properties only where the application can make a meaningful decision, such as prompting for credentials, surfacing a not-found condition, or stopping after user cancellation.
Sources: src/client.ts
Retries, Timeouts, and Aborts
Retry and timeout behavior belong to client configuration and request execution, not to individual resource models. The client source imports request-option utilities, a sleep helper, positive-integer validation, and abort-error detection, which are the building blocks for enforcing retry delays, validating numeric configuration, and distinguishing a user or system abort from a server response. Treat retries as a resilience mechanism for transient failures, not as a substitute for idempotency design. If a request creates external side effects, ensure your surrounding workflow can tolerate a repeated attempt before increasing retry counts.
Sources: src/client.ts
Timeout troubleshooting should begin with the type of failure and the operation being performed. A short timeout can be useful for interactive user actions, while longer-running file, batch, streaming, or tool-enabled operations may need different request-level settings. When an abort happens, the client’s abort detection path helps classify it separately from an API status error. At the application layer, preserve the original error object, include the operation name in your logs, and avoid automatically retrying a request that the user intentionally cancelled. This keeps cancellation responsive and prevents background work from continuing unexpectedly.
Sources: src/client.ts, tests/index.test.ts
Logging and Redaction
The SDK exposes logging through client options and generated logging types. Tests construct a client with a custom logger and a debug log level, force an API response through the API promise path, and assert that debug logging occurs. The same test group checks that the default log level is warning-oriented, which means most applications should not emit verbose request details unless they explicitly opt in. Use debug logging during integration, staging, or a short production incident window, then return to a quieter level once the failing request pattern is understood.
Sources: src/client.ts, tests/index.test.ts
The log tests provide an important safety signal: authorization headers are redacted in debug output. They create clients with authorization data in request and default header paths, run requests through a custom fetch implementation, and assert that the logged header value is masked. They also verify that input header objects are not mutated by the redaction process. That distinction matters for shared configuration objects, because a logger should protect secrets in output without changing the values the actual request uses or surprising other code that reuses the same object.
Sources: tests/log.test.ts
Troubleshooting Flow
Start by confirming configuration. The README shows the usual API-key path, where the client reads an environment variable by default, and the tests show that default headers can be provided, preserved, removed with a null value, or left unchanged when a request passes undefined. If authentication fails, compare the configured key, organization or project context, base URL, and any custom headers against the environment that actually runs the process. Header removal is intentional behavior, so check for request-level overrides before assuming the SDK dropped a header unexpectedly.
Sources: README.md, tests/index.test.ts
Next, reproduce with diagnostic logging and a minimal request. Set a debug log level or provide a logger that records structured fields, then run the smallest request that still fails. Inspect whether the request was sent, whether the response was received, and whether the failure is an API error, an abort, or a transport issue. Avoid pasting raw logs into bug reports without checking redaction boundaries, especially if custom headers carry credentials other than the standard authorization header. The tests demonstrate redaction for authorization, but application-specific secrets should still be treated carefully.
Sources: tests/index.test.ts, tests/log.test.ts
Compact Reference
| Concern | SDK-facing control or signal | Practical use |
|---|---|---|
| Authentication failures | Client API key and default headers | Verify credentials before debugging resource-specific code. |
| API errors | Generated error module and typed error classes | Branch only when recovery differs by error type. |
| User cancellation | Abort-error detection path | Do not retry deliberate cancellation. |
| Retries | Request options, validation helpers, and retry delay support | Tune for transient failures while respecting side effects. |
| Timeouts | Request-level execution options and abort handling | Use operation-appropriate limits. |
| Logging | logger, logLevel, OPENAI_LOG, DEBUG-related test setup | Enable temporarily to inspect request and response flow. |
| Secret handling | Authorization redaction in debug logs | Keep diagnostics useful without exposing credentials. |
A good production pattern is to centralize SDK client construction, set conservative defaults there, and allow request-level overrides only where a feature has a clear need. Wrap each external call with application context, catch errors at the service boundary, and convert them into user-facing messages or retry decisions outside the resource call itself. For the next step, read the client configuration page for construction options, then review the resource-specific page for the API you are calling so that status errors can be interpreted alongside that endpoint’s request and response model.
Sources: README.md, src/client.ts, tests/index.test.ts, tests/log.test.ts