## Phase 8: Enterprise Extractor Improvements ✅ - 14 security extractors (TLS, JWT, SQL injection, XSS, etc.) - 10 framework-specific extractors (Spring, Django, Rails, etc.) - Config file security detection (YAML, TOML) ## Phase 9: Autonomous Extractor Generation ✅ - Shadow mode executor with TP/FP tracking - Graduation pipeline with confidence thresholds - Auto-rollback on regression detection - Cross-project pattern syncing ## UAT Suite Complete (14 scripts, 90 tests) - test-core-detection.sh (6 tests) - test-declarative-extractors.sh (5 tests) - test-domain-frameworks.sh (5 tests) - test-domain-unreal.sh (3 tests) - test-llm-extraction.sh (6 tests) - test-eval-harness.sh (5 tests) - test-cross-language.sh (3 tests) - test-precommit-performance.sh (4 tests) - test-output-formats.sh (8 tests) - test-drift-detection.sh (6 tests) - test-exit-codes.sh (12 tests) + 3 more scripts ## Other Changes - Updated roadmap to mark Phase 8-9 complete - Added .gitignore entries for build artifacts - Updated pre-commit: 800 line limit, exclude tests/data/cmd Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
103 lines
3.0 KiB
Go
103 lines
3.0 KiB
Go
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)
|
|
}
|