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, BankSubmissionError, BatchValidationError, HistorySyncForbiddenError, InternalServerError, InvalidCountError, InvalidCursorError, InvalidDateRangeError, InvalidLimitError, InvalidOrderStateError, InvalidQueryError, MissingDateRangeError, MutationDuringPaginationError, NotFoundError, RateLimitExceededError, ServiceUnavailableError, SyncInProgressError, SyncRateLimitExceededError, UnauthorizedError, UnprocessableContentError, ValidationError, 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 |