Module: ApiBrasil::Core::Errors::ErrorFactory

Defined in:
lib/api_brasil/core/errors.rb

Overview

Mapeia um status HTTP + corpo de erro para a subclasse adequada de ApiBrasilError (equivalente ao createApiError da SDK JS).

Class Method Summary collapse

Class Method Details

.create(status, data, headers = nil, previous = nil) ⇒ ApiBrasilError

Parameters:

  • status (Integer)
  • data (Object)

    corpo da resposta ja decodificado

  • headers (Hash{String => String}, nil) (defaults to: nil)
  • previous (Exception, nil) (defaults to: nil)

Returns:



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/api_brasil/core/errors.rb', line 104

def create(status, data, headers = nil, previous = nil)
  message = extract_message(status, data)
  options = {
    status: status,
    code: extract_code(data),
    response: data,
    previous: previous
  }

  case status
  when 400, 422 then ValidationError.new(message, **options)
  when 401 then AuthenticationError.new(message, **options)
  when 402 then InsufficientBalanceError.new(message, **options)
  when 403 then PermissionError.new(message, **options)
  when 404, 410 then NotFoundError.new(message, **options)
  when 429 then RateLimitError.new(message, retry_after_ms: parse_retry_after(headers), **options)
  else
    status >= 500 ? ServerError.new(message, **options) : ApiBrasilError.new(message, **options)
  end
end

.extract_code(data) ⇒ String?

Returns:

  • (String, nil)


139
140
141
142
143
144
# File 'lib/api_brasil/core/errors.rb', line 139

def extract_code(data)
  return nil unless data.is_a?(Hash)

  code = data["code"] || data[:code]
  code.is_a?(String) ? code : nil
end

.extract_message(status, data) ⇒ String

Returns:

  • (String)


126
127
128
129
130
131
132
133
134
135
136
# File 'lib/api_brasil/core/errors.rb', line 126

def extract_message(status, data)
  if data.is_a?(Hash)
    message = data["message"] || data[:message]
    return message if message.is_a?(String) && !message.empty?

    error = data["error"] || data[:error]
    return error if error.is_a?(String) && !error.empty?
  end

  "A API respondeu com HTTP #{status}."
end

.parse_retry_after(headers) ⇒ Integer?

Le o header Retry-After (segundos ou data HTTP) e devolve ms.

Returns:

  • (Integer, nil)


149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/api_brasil/core/errors.rb', line 149

def parse_retry_after(headers)
  return nil unless headers.is_a?(Hash)

  raw = headers["retry-after"] || headers["Retry-After"]
  return nil if raw.nil? || raw.to_s.empty?

  raw = raw.to_s
  return [0, (raw.to_f * 1000).round].max if raw.match?(/\A\s*-?\d+(\.\d+)?\s*\z/)

  begin
    [0, ((Time.httpdate(raw) - Time.now) * 1000).round].max
  rescue ArgumentError
    nil
  end
end