Module: OllamaAgent::Providers::ErrorClassifier
- Defined in:
- lib/ollama_agent/providers/error_classifier.rb
Overview
Maps raw HTTP errors and Ruby exceptions into the typed OllamaAgent error hierarchy so that the CredentialRouter can apply the correct cooldown and retry strategy without coupling to provider-specific error messages.
Classification rules (in priority order):
HTTP 401 / 403 → AuthenticationError (permanent disable)
HTTP 402 → QuotaExhaustedError (long cooldown)
HTTP 429 + quota phrasing → QuotaExhaustedError
HTTP 429 (plain) → RateLimitError
HTTP 5xx → TemporaryProviderError (brief cooldown)
Timeout / network → TemporaryProviderError
Unknown → re-raised as-is
Constant Summary collapse
- QUOTA_PHRASES =
Phrases that signal a long-term quota exhaustion rather than a short rate-limit window. Matched case-insensitively against error.message.
[ "quota", "exceeded", "daily_limit", "monthly_limit", "weekly_limit", "billing", "insufficient_quota", "run out of credits", "weekly usage limit", "monthly usage limit", "exceeded your current quota", "you have run out" ].freeze
Class Method Summary collapse
-
.classify(error, http_status: nil) ⇒ OllamaAgent::Error
Classify a raw error into a typed OllamaAgent error.
- .classify_by_status(status, error) ⇒ Object
- .classify_network(error) ⇒ Object
- .extract_http_status(error) ⇒ Object
- .network_error?(error) ⇒ Boolean
- .permanently_disabling?(error) ⇒ Boolean
- .quota_exhaustion_message?(error) ⇒ Boolean
- .quota_phrased?(msg) ⇒ Boolean
- .retryable_with_other_credential?(error) ⇒ Boolean
Class Method Details
.classify(error, http_status: nil) ⇒ OllamaAgent::Error
Classify a raw error into a typed OllamaAgent error.
31 32 33 34 35 36 37 38 |
# File 'lib/ollama_agent/providers/error_classifier.rb', line 31 def classify(error, http_status: nil) status = http_status || extract_http_status(error) return classify_by_status(status, error) if status && !status.zero? return classify_network(error) if network_error?(error) error # pass through — caller should re-raise end |
.classify_by_status(status, error) ⇒ Object
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/ollama_agent/providers/error_classifier.rb', line 61 def self.classify_by_status(status, error) msg = error..to_s case status when 401, 403 if msg.match?(/subscription/i) OllamaAgent::SubscriptionRequiredError.new(msg) else OllamaAgent::AuthenticationError.new(msg) end when 402 OllamaAgent::QuotaExhaustedError.new(msg) when 429 if quota_phrased?(msg) OllamaAgent::QuotaExhaustedError.new(msg) else OllamaAgent::RateLimitError.new(msg) end when 500..599 OllamaAgent::TemporaryProviderError.new(msg) else error end end |
.classify_network(error) ⇒ Object
85 86 87 |
# File 'lib/ollama_agent/providers/error_classifier.rb', line 85 def self.classify_network(error) OllamaAgent::TemporaryProviderError.new(error.) end |
.extract_http_status(error) ⇒ Object
89 90 91 |
# File 'lib/ollama_agent/providers/error_classifier.rb', line 89 def self.extract_http_status(error) error..to_s[/\b(\d{3})\b/, 1].to_i end |
.network_error?(error) ⇒ Boolean
98 99 100 101 102 103 104 |
# File 'lib/ollama_agent/providers/error_classifier.rb', line 98 def self.network_error?(error) error.is_a?(Timeout::Error) || error.is_a?(Errno::ECONNREFUSED) || error.is_a?(Errno::ECONNRESET) || error.is_a?(Errno::ETIMEDOUT) || (defined?(SocketError) && error.is_a?(SocketError)) end |
.permanently_disabling?(error) ⇒ Boolean
42 43 44 |
# File 'lib/ollama_agent/providers/error_classifier.rb', line 42 def permanently_disabling?(error) error.is_a?(OllamaAgent::AuthenticationError) end |
.quota_exhaustion_message?(error) ⇒ Boolean
57 58 59 |
# File 'lib/ollama_agent/providers/error_classifier.rb', line 57 def (error) quota_phrased?(error..to_s) end |
.quota_phrased?(msg) ⇒ Boolean
93 94 95 96 |
# File 'lib/ollama_agent/providers/error_classifier.rb', line 93 def self.quota_phrased?(msg) m = msg.to_s.downcase QUOTA_PHRASES.any? { |phrase| m.include?(phrase) } end |
.retryable_with_other_credential?(error) ⇒ Boolean
48 49 50 51 52 53 |
# File 'lib/ollama_agent/providers/error_classifier.rb', line 48 def retryable_with_other_credential?(error) error.is_a?(OllamaAgent::RateLimitError) || error.is_a?(OllamaAgent::QuotaExhaustedError) || error.is_a?(OllamaAgent::TemporaryProviderError) || error.is_a?(OllamaAgent::SubscriptionRequiredError) end |