73 lines
1.8 KiB
Ruby
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
|