Module: ActiveAgent::Providers::Errors::Taxonomy
- Defined in:
- lib/active_agent/providers/errors.rb
Overview
Classifies vendor SDK exceptions into the taxonomy. Unrecognizable exceptions (including ordinary Ruby errors) pass through untouched — only errors that look like vendor API failures are normalized.
Constant Summary collapse
- NAME_MAP =
Vendor SDK class names (demodulized) → taxonomy class. Covers the official anthropic/openai gems and SDKs following their naming.
{ "RateLimitError" => RateLimited, "AuthenticationError" => AuthenticationFailed, "PermissionDeniedError" => AuthenticationFailed, "ContentFilterError" => ContentFiltered, "InternalServerError" => ServiceUnavailable, "APIConnectionError" => ServiceUnavailable, "APIConnectionTimeoutError" => ServiceUnavailable, "APITimeoutError" => ServiceUnavailable, "OverloadedError" => ServiceUnavailable, "ServiceUnavailableError" => ServiceUnavailable, "BadRequestError" => InvalidRequest, "UnprocessableEntityError" => InvalidRequest }.freeze
- STATUS_MAP =
{ 400 => InvalidRequest, 401 => AuthenticationFailed, 403 => AuthenticationFailed, 408 => ServiceUnavailable, 422 => InvalidRequest, 429 => RateLimited, 529 => ServiceUnavailable # Anthropic "overloaded" }.freeze
- CONTEXT_LENGTH_PATTERN =
/context length|context_length|maximum context|context window|too many tokens|prompt is too long|input (?:is )?too long/i- CONTENT_FILTER_PATTERN =
/content (?:filter|policy|management)|filtered due to|blocked by|safety (?:system|filter)/i
Class Method Summary collapse
- .classify(exception) ⇒ Class?
-
.normalize(exception, provider_tag: nil) ⇒ Exception
A taxonomy error, or the original exception when it doesn't classify.
- .status_of(exception) ⇒ Integer?
Class Method Details
.classify(exception) ⇒ Class?
109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/active_agent/providers/errors.rb', line 109 def classify(exception) name = exception.class.name.to_s.demodulize status = status_of(exception) api_error = NAME_MAP.key?(name) || !status.nil? return nil unless api_error = exception..to_s return ContextLengthExceeded if CONTEXT_LENGTH_PATTERN.match?() return ContentFiltered if CONTENT_FILTER_PATTERN.match?() NAME_MAP[name] || STATUS_MAP[status] || (status && status >= 500 ? ServiceUnavailable : nil) end |
.normalize(exception, provider_tag: nil) ⇒ Exception
Returns a taxonomy error, or the original exception when it doesn't classify.
99 100 101 102 103 104 105 106 |
# File 'lib/active_agent/providers/errors.rb', line 99 def normalize(exception, provider_tag: nil) return exception if exception.is_a?(ProviderError) klass = classify(exception) return exception unless klass klass.new(exception., status: status_of(exception), provider_tag: provider_tag) end |
.status_of(exception) ⇒ Integer?
123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/active_agent/providers/errors.rb', line 123 def status_of(exception) [ :status, :status_code, :http_status, :code ].each do |reader| next unless exception.respond_to?(reader) value = begin exception.public_send(reader) rescue StandardError nil end return value if value.is_a?(Integer) end nil end |