Exception: Multilocale::ApiError

Inherits:
Error
  • Object
show all
Defined in:
lib/multilocale/errors.rb

Overview

The server answered with a status >= 400.

Constant Summary collapse

STATUS_CLASSES =
{
  401 => "AuthenticationError",
  403 => "PermissionError",
  404 => "NotFoundError",
  429 => "RateLimitedError"
}.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(message, status: nil, body: nil, request_method: nil, url: nil) ⇒ ApiError

Returns a new instance of ApiError.



19
20
21
22
23
24
25
# File 'lib/multilocale/errors.rb', line 19

def initialize(message, status: nil, body: nil, request_method: nil, url: nil)
  super(message)
  @status = status
  @body = body
  @request_method = request_method
  @url = url
end

Instance Attribute Details

#bodyObject (readonly)

Returns the value of attribute body.



17
18
19
# File 'lib/multilocale/errors.rb', line 17

def body
  @body
end

#request_methodObject (readonly)

Returns the value of attribute request_method.



17
18
19
# File 'lib/multilocale/errors.rb', line 17

def request_method
  @request_method
end

#statusObject (readonly)

Returns the value of attribute status.



17
18
19
# File 'lib/multilocale/errors.rb', line 17

def status
  @status
end

#urlObject (readonly)

Returns the value of attribute url.



17
18
19
# File 'lib/multilocale/errors.rb', line 17

def url
  @url
end

Class Method Details

.build(status:, payload:, raw_body:, request_method:, url:) ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/multilocale/errors.rb', line 45

def self.build(status:, payload:, raw_body:, request_method:, url:)
  message = payload.is_a?(Hash) ? payload["message"] : nil
  message = "HTTP #{status}" if message.nil? || message.to_s.empty?

  class_for(status).new(
    "#{message} (#{request_method.to_s.upcase} #{url} -> #{status})#{hint_for(status)}",
    status: status,
    body: payload || raw_body,
    request_method: request_method,
    url: url
  )
end

.class_for(status) ⇒ Object

Maps an HTTP status onto the narrowest error class. 5xx is a single ServerError: the API returns the same {status, message} envelope for all of them and callers treat them identically (retry, then give up).



37
38
39
40
41
42
43
# File 'lib/multilocale/errors.rb', line 37

def self.class_for(status)
  name = STATUS_CLASSES[status]
  return Multilocale.const_get(name) if name
  return ServerError if status >= 500

  self
end

.hint_for(status) ⇒ Object

The two failures every new integration hits, answered in the message itself rather than in a doc the reader is not looking at.



60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/multilocale/errors.rb', line 60

def self.hint_for(status)
  case status
  when 401
    "\nCheck MULTILOCALE_API_KEY: the API expects Basic base64(secret) — the key secret alone, " \
      "not key:secret."
  when 403
    "\nThe key is valid but not allowed here: a missing scope (projects:read, phrases:write, …) " \
      "or a key scoped to a different project."
  else
    ""
  end
end