Files
fiken-api/lib/fiken/error.rb
T

73 lines
1.8 KiB
Ruby

# frozen_string_literal: true
module Fiken
# Base class for all errors raised by the gem.
class Error < StandardError
attr_reader :status, :body, :response
def initialize(message = nil, status: nil, body: nil, response: nil)
@status = status
@body = body
@response = response
super(message || "Fiken API error (HTTP #{status})")
end
# Builds the most specific error subclass for an HTTP response.
def self.from_response(status, body, response = nil)
klass = STATUS_MAP[status] || (status >= 500 ? ServerError : self)
klass.new(extract_message(body), status: status, body: body, response: response)
end
def self.extract_message(body)
case body
when String then body.empty? ? nil : body
when Hash then hash_message(body)
end
end
def self.hash_message(body)
%w[message error_description error].each do |key|
value = body[key]
return value if value
end
messages = Array(body["validation_messages"])
messages.join(", ") unless messages.empty?
end
end
# Raised when the request never reached Fiken (timeout, DNS, connection reset).
class ConnectionError < Error; end
# 400
class BadRequest < Error; end
# 401
class Unauthorized < Error; end
# 403
class Forbidden < Error; end
# 404
class NotFound < Error; end
# 406
class NotAcceptable < Error; end
# 409
class Conflict < Error; end
# 422
class UnprocessableEntity < Error; end
# 429
class RateLimited < Error; end
# 5xx
class ServerError < Error; end
class Error
STATUS_MAP = {
400 => BadRequest,
401 => Unauthorized,
403 => Forbidden,
404 => NotFound,
406 => NotAcceptable,
409 => Conflict,
422 => UnprocessableEntity,
429 => RateLimited
}.freeze
end
end