Exception: TesoteSdk::ApiError
- Defined in:
- lib/tesote_sdk/errors.rb
Overview
Server returned a usable HTTP response with an error.
Direct Known Subclasses
AccountDisabledError, ApiKeyRevokedError, HistorySyncForbiddenError, InvalidDateRangeError, MutationDuringPaginationError, RateLimitExceededError, ServiceUnavailableError, UnauthorizedError, UnprocessableContentError, WorkspaceSuspendedError
Constant Summary collapse
- CODE_REGISTRY =
Map error_code → typed subclass. Unknown codes fall back to ApiError.
{}
Instance Attribute Summary
Attributes inherited from Error
#attempts, #error_code, #error_id, #http_status, #request_id, #request_summary, #response_body, #retry_after
Class Method Summary collapse
-
.from_response(response, body, request_summary, attempts: 1) ⇒ Object
why: single dispatcher used by Transport — keeps mapping logic out of caller paths.
- .parse_body(body) ⇒ Object
- .parse_retry_after(response, envelope_value) ⇒ Object
- .pick_class(http_status, error_code) ⇒ Object
-
.register(code, klass) ⇒ Object
rubocop:disable Style/MutableConstant – registered via .register at load time.
- .synthesize_message(response) ⇒ Object
Methods inherited from Error
#cause, #initialize, #inspect, #to_h
Constructor Details
This class inherits a constructor from TesoteSdk::Error
Class Method Details
.from_response(response, body, request_summary, attempts: 1) ⇒ Object
why: single dispatcher used by Transport — keeps mapping logic out of caller paths.
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/tesote_sdk/errors.rb', line 76 def self.from_response(response, body, request_summary, attempts: 1) parsed = parse_body(body) envelope = parsed.is_a?(Hash) ? parsed : {} error_code = envelope['error_code'] = envelope['error'] || (response) error_id = envelope['error_id'] retry_after_value = parse_retry_after(response, envelope['retry_after']) request_id = response['x-request-id'] || response['X-Request-Id'] http_status = response.code.to_i klass = pick_class(http_status, error_code) klass.new( , error_code: error_code, http_status: http_status, request_id: request_id, error_id: error_id, retry_after: retry_after_value, response_body: body, request_summary: request_summary, attempts: attempts ) end |
.parse_body(body) ⇒ Object
107 108 109 110 111 112 113 |
# File 'lib/tesote_sdk/errors.rb', line 107 def self.parse_body(body) return nil if body.nil? || body.empty? JSON.parse(body) rescue JSON::ParserError nil end |
.parse_retry_after(response, envelope_value) ⇒ Object
119 120 121 122 123 124 125 126 |
# File 'lib/tesote_sdk/errors.rb', line 119 def self.parse_retry_after(response, envelope_value) header = response['retry-after'] || response['Retry-After'] return Integer(header) if header && header.match?(/\A\d+\z/) return Integer(envelope_value) if envelope_value.is_a?(Integer) return Integer(envelope_value) if envelope_value.is_a?(String) && envelope_value.match?(/\A\d+\z/) nil end |
.pick_class(http_status, error_code) ⇒ Object
100 101 102 103 104 105 |
# File 'lib/tesote_sdk/errors.rb', line 100 def self.pick_class(http_status, error_code) return CODE_REGISTRY[error_code] if error_code && CODE_REGISTRY.key?(error_code) return ServiceUnavailableError if http_status == 503 ApiError end |
.register(code, klass) ⇒ Object
rubocop:disable Style/MutableConstant – registered via .register at load time
71 72 73 |
# File 'lib/tesote_sdk/errors.rb', line 71 def self.register(code, klass) CODE_REGISTRY[code] = klass end |
.synthesize_message(response) ⇒ Object
115 116 117 |
# File 'lib/tesote_sdk/errors.rb', line 115 def self.(response) "HTTP #{response.code} #{response.}" end |