Module: Onetime::Errors
- Defined in:
- lib/onetime/errors.rb
Overview
Builds the appropriate APIError subclass from an HTTP response.
Constant Summary collapse
- ACCOUNT_REQUIRED_MESSAGE =
Used only when the server sends no message of its own.
"This operation requires an authenticated account: send your " \ "customer extid and API token (see Onetime::Client.new)."
- ERROR_TYPE_MAP =
Maps the ADR-013 error_type (the machine-readable class name the server sends) to a client exception class. Falls through to status code mapping when the type is absent or unrecognized.
{ "FormError" => BadRequestError, "RequiresAccount" => AccountRequiredError, "AccountRequired" => AccountRequiredError, "RecordNotFound" => NotFoundError, "NotFound" => NotFoundError, "Forbidden" => ForbiddenError, "GuestRoutesDisabled" => ForbiddenError, "EntitlementRequired" => EntitlementError, "LimitExceeded" => RateLimitError, "ServerError" => ServerError, }.freeze
- ACCOUNT_REQUIRED_KEYS =
The account requirement can arrive in any of several slots depending on the endpoint and API version: as the FormError
field, as the i18nerror_key, or as acode. Matching all of them keeps the mapping stable across server versions. %w[error_type field error_key code].freeze
- ACCOUNT_REQUIRED_PATTERN =
Matches the bare token as well as prefixed codes such as "GUEST_CONCEAL_REQUIRES_ACCOUNT" (underscores are word characters, so \b is no help here).
/(?:\A|[^a-z0-9])(requires[_-]?account|account[_-]?required)(?:\z|[^a-z0-9])/i- STATUS_MAP =
{ 400 => BadRequestError, 401 => AuthenticationError, 403 => ForbiddenError, 404 => NotFoundError, 409 => ConflictError, 422 => BadRequestError, 429 => RateLimitError, }.freeze
Class Method Summary collapse
-
.account_required?(body) ⇒ Boolean
True when the body says the operation needs an authenticated account, in whichever slot this server version reports it.
- .default_message(status) ⇒ Object
- .error_class(error_type, status) ⇒ Object
- .from_response(response) ⇒ Onetime::APIError
Class Method Details
.account_required?(body) ⇒ Boolean
True when the body says the operation needs an authenticated account, in whichever slot this server version reports it.
136 137 138 139 140 |
# File 'lib/onetime/errors.rb', line 136 def account_required?(body) ACCOUNT_REQUIRED_KEYS.any? do |key| ACCOUNT_REQUIRED_PATTERN.match?(body[key].to_s) end end |
.default_message(status) ⇒ Object
148 149 150 151 152 153 154 155 156 157 158 |
# File 'lib/onetime/errors.rb', line 148 def (status) case status when 400 then "Bad request" when 401 then "Authentication failed" when 403 then "Forbidden" when 404 then "Not found" when 429 then "Rate limit exceeded" when 500..599 then "Server error (#{status})" else "Request failed (#{status})" end end |
.error_class(error_type, status) ⇒ Object
142 143 144 145 146 |
# File 'lib/onetime/errors.rb', line 142 def error_class(error_type, status) ERROR_TYPE_MAP[error_type] || STATUS_MAP[status] || (status.to_i >= 500 ? ServerError : APIError) end |
.from_response(response) ⇒ Onetime::APIError
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/onetime/errors.rb', line 111 def from_response(response) body = response.data.is_a?(Hash) ? response.data : {} status = response.http_status account = account_required?(body) klass = account ? AccountRequiredError : error_class(body["error_type"], status) = body["error"] || body["message"] || (account ? ACCOUNT_REQUIRED_MESSAGE : (status)) klass.new( , http_status: status, error_type: body["error_type"], code: body["code"], field: body["field"], error_key: body["error_key"], retry_after: body["retry_after"], entitlement: body["entitlement"], body: response.data, response: response, ) end |