Error Handling & Retries
Relevant source files
The following files were used as context for generating this wiki page:
The Speech SDK implements a robust error handling and retry system designed to provide consistent behavior across 13 different AI speech providers. The system differentiates between permanent client errors (such as invalid API keys or malformed input) and transient provider issues (such as network timeouts or server-side 5xx errors).
The primary mechanism for resilience is built directly into the public entry point generateSpeech(), which utilizes exponential backoff for retrying failed requests. Error reporting is handled through a hierarchy of custom TypeScript error classes, allowing developers to programmatically catch and respond to specific failure modes such as rate limiting or unsupported streaming capabilities.
Sources: AGENTS.md, README.md, skills/speech-sdk/references/error-handling.md
Error Hierarchy
All errors thrown by the SDK inherit from a base SpeechSDKError class. This hierarchy ensures that users can catch all SDK-related issues in a single block or drill down into specific error types for more granular handling.
Core Error Classes
| Error | Description |
|---|---|
SpeechSDKError | The base class for all errors within the SDK. |
ApiError | Thrown when a provider returns a non-2xx response. Includes status codes and raw response bodies. |
NoSpeechGeneratedError | Thrown if input text is empty (after tag stripping) or if the provider returns a 2xx with no audio data. |
StreamingNotSupportedError | Thrown when streamSpeech() is called on a model that does not support streaming. |
VolumeAdjustmentUnsupportedError | Thrown when volumeDbfs is requested but the output mode cannot be decoded to PCM/WAV. |
TimestampKeyMissingError | Thrown when timestamps: "on" is requested but the fallback STT API key is missing. |
Sources: skills/speech-sdk/references/error-handling.md:5-13, src/errors.ts, README.md
Conversation & Dialogue Errors
Specific errors are reserved for the generateConversation workflow to handle complexities in multi-speaker stitching and native dialogue endpoints.
| Error | Triggering Condition |
|---|---|
ConversationInputError | Invalid turns or configuration provided to the conversation generator. |
DialogueConstraintError | A native dialogue endpoint cannot satisfy the request (e.g., too many voices). |
StitchUnsupportedError | A provider is used that cannot emit the PCM/WAV data required for local stitching. |
Sources: src/conversation/errors.ts, src/tests/conversation-errors.test.ts:16-30
Retry Logic and Backoff
The SDK automatically retries failed requests to improve reliability against transient network or provider errors. This logic is powered by the p-retry dependency.
Retry Strategy
- Targeted Errors: The SDK retries 5xx server errors and network-level failures.
- Excluded Errors: 4xx client errors (e.g.,
401 Unauthorized,429 Rate Limited) are not retried as they represent permanent issues or require intentional throttling. - Backoff: Retries use exponential backoff to avoid overwhelming provider APIs.
- Default configuration: The SDK defaults to 2 retries.
Sources: skills/speech-sdk/references/error-handling.md:39-44, src/generate-speech.ts, AGENTS.md
Configuration
Users can customize the retry behavior through the maxRetries option in the generateSpeech and generateConversation functions.
// Custom retry configuration
await generateSpeech({
model: "openai/tts-1",
text: "Hello",
voice: "alloy",
maxRetries: 5 // Increase retries for unstable environments
});
// Disable retries
await generateSpeech({
model: "openai/tts-1",
text: "Hello",
voice: "alloy",
maxRetries: 0
});
Sources: skills/speech-sdk/references/error-handling.md:41-44, README.md
Internal Error Flow
The following diagram illustrates how the SDK processes a speech generation request and handles potential failures at different stages.
The diagram shows the logic flow from the initial API call through the retry mechanism and final error classification.
Sources: src/generate-speech.ts, src/provider-utils.ts, skills/speech-sdk/references/error-handling.md
Provider-Specific Error Handling
Providers often return errors in varied formats. The SDK uses handleErrorResponse internally to normalize these into the standard ApiError class.
ApiError Structure
The ApiError class captures critical debugging information from the provider response:
statusCode: The HTTP status code (e.g., 401, 403, 429, 500).model: The model identifier used during the request.responseBody: The raw body returned by the API (often contains provider-specific error messages).
Sources: skills/speech-sdk/references/error-handling.md:23-28, src/provider-utils.ts
Dialogue Constraints
For generateConversation, the SDK validates "Native Dialogue" constraints before calling the provider. If a provider's specific rules (like Google Gemini requiring exactly 2 voices) are violated, a DialogueConstraintError is thrown before any network request is made.
This sequence highlights the pre-request validation for dialogue and the immediate failure on 4xx responses.
Sources: src/conversation/errors.ts, src/tests/conversation-errors.test.ts:16-30, skills/speech-sdk/references/error-handling.md:39-40
Implementation Standards
As per the project's architecture, specific coding standards are enforced for error handling:
- Error Objects: Always throw
Errorobjects with descriptive messages; never throw strings. - Early Returns: Use early returns instead of nested conditionals to handle error states.
- Rethrowing: Do not catch errors just to rethrow them unless adding significant context.
- Unknown Type: In accordance with TypeScript strict mode, the SDK prefers
unknownoveranyfor error properties likeresponseBody.
Sources: AGENTS.md:65-69, 78-80
The SDK's error handling and retry system ensures that developers can build resilient applications by abstracting the complexities of 13 different provider APIs into a unified, predictable interface.