package elevenlabs import ( "errors" "fmt" "pitch-voiceover/pkg/httpkit" ) // Sentinel errors for common error types. // These are aliases for httpkit sentinels, so errors.Is works with either. var ( // ErrInvalidConfig indicates configuration validation failed ErrInvalidConfig = errors.New("elevenlabs: invalid configuration") // ErrQuotaExceeded indicates the API quota has been exceeded ErrQuotaExceeded = errors.New("elevenlabs: quota exceeded") // ErrVoiceNotFound indicates the requested voice does not exist ErrVoiceNotFound = errors.New("elevenlabs: voice not found") // ErrRateLimit indicates rate limit exceeded (HTTP 429) ErrRateLimit = httpkit.ErrRateLimit // ErrServerError indicates server-side error (HTTP 5xx) ErrServerError = httpkit.ErrServerError // ErrInvalidRequest indicates client error (HTTP 4xx except 429, 401) ErrInvalidRequest = httpkit.ErrBadRequest // ErrTimeout indicates request timeout ErrTimeout = httpkit.ErrTimeout // ErrUnauthorized indicates authentication failed (HTTP 401) ErrUnauthorized = httpkit.ErrUnauthorized ) // APIError represents an error returned by the ElevenLabs API type APIError struct { StatusCode int // HTTP status code Message string // Human-readable error message Status string // Status from API response (e.g., "quota_exceeded") err error // Underlying error for wrapping } // Error implements the error interface func (e *APIError) Error() string { if e.Status != "" { return fmt.Sprintf("elevenlabs api error (status %d): [%s] %s", e.StatusCode, e.Status, e.Message) } return fmt.Sprintf("elevenlabs api error (status %d): %s", e.StatusCode, e.Message) } // Unwrap implements the errors.Unwrap interface for error chains func (e *APIError) Unwrap() error { return e.err } // NewAPIError creates a new APIError with the given parameters func NewAPIError(statusCode int, message, status string, underlying error) *APIError { return &APIError{ StatusCode: statusCode, Message: message, Status: status, err: underlying, } } // IsRateLimitError checks if the error is a rate limit error func IsRateLimitError(err error) bool { return errors.Is(err, ErrRateLimit) } // IsServerError checks if the error is a server error (5xx) func IsServerError(err error) bool { return errors.Is(err, ErrServerError) } // IsRetryableError checks if the error should trigger a retry func IsRetryableError(err error) bool { return httpkit.IsRetryable(err) } // IsUnauthorizedError checks if the error is an unauthorized error (401) func IsUnauthorizedError(err error) bool { return errors.Is(err, ErrUnauthorized) } // IsTimeoutError checks if the error is a timeout error func IsTimeoutError(err error) bool { return errors.Is(err, ErrTimeout) } // IsQuotaExceededError checks if the error is a quota exceeded error func IsQuotaExceededError(err error) bool { return errors.Is(err, ErrQuotaExceeded) } // IsVoiceNotFoundError checks if the error is a voice not found error func IsVoiceNotFoundError(err error) bool { return errors.Is(err, ErrVoiceNotFound) }