module Asana::HttpClient::ErrorHandling

Internal: Handles errors from the API and re-raises them as proper exceptions.

Constants

MAX_TIMEOUTS

Public Instance Methods

api_error(response) click to toggle source

Internal: Returns an APIError exception.

# File lib/asana/http_client/error_handling.rb, line 102
def api_error(response)
  APIError.new.tap { |exception| exception.response = response }
end
body(response) click to toggle source

Internal: Parser a response body from JSON.

# File lib/asana/http_client/error_handling.rb, line 107
def body(response)
  MultiJson.load(response[:body])
end
forbidden(response) click to toggle source

Internal: Returns a Forbidden exception.

# File lib/asana/http_client/error_handling.rb, line 75
def forbidden(response)
  Forbidden.new.tap { |exception| exception.response = response }
end
handle(num_timeouts=0, &request) click to toggle source

Public: Perform a request handling any API errors correspondingly.

request - [Proc] a block that will execute the request.

Returns a [Faraday::Response] object.

Raises [Asana::Errors::InvalidRequest] for invalid requests. Raises [Asana::Errors::NotAuthorized] for unauthorized requests. Raises [Asana::Errors::Forbidden] for forbidden requests. Raises [Asana::Errors::NotFound] when a resource can't be found. Raises [Asana::Errors::RateLimitEnforced] when the API is throttling. Raises [Asana::Errors::ServerError] when there's a server problem. Raises [Asana::Errors::APIError] when the API returns an unknown error.

rubocop:disable all

# File lib/asana/http_client/error_handling.rb, line 31
def handle(num_timeouts=0, &request)
  request.call
rescue Faraday::ClientError => e
  raise e unless e.response
  case e.response[:status]
    when 400 then raise invalid_request(e.response)
    when 401 then raise not_authorized(e.response)
    when 402 then raise payment_required(e.response)
    when 403 then raise forbidden(e.response)
    when 404 then raise not_found(e.response)
    when 412 then recover_response(e.response)
    when 429 then raise rate_limit_enforced(e.response)
    when 500 then raise server_error(e.response)
    else raise api_error(e.response)
  end
rescue Net::ReadTimeout => e
  if num_timeouts < MAX_TIMEOUTS
    handle(num_timeouts + 1, &request)
  else
    raise e
  end
end
invalid_request(response) click to toggle source

Internal: Returns an InvalidRequest exception including a list of errors.

# File lib/asana/http_client/error_handling.rb, line 57
def invalid_request(response)
  errors = body(response).fetch('errors', []).map { |e| e['message'] }
  InvalidRequest.new(errors).tap do |exception|
    exception.response = response
  end
end
not_authorized(response) click to toggle source

Internal: Returns a NotAuthorized exception.

# File lib/asana/http_client/error_handling.rb, line 65
def not_authorized(response)
  NotAuthorized.new.tap { |exception| exception.response = response }
end
not_found(response) click to toggle source

Internal: Returns a NotFound exception.

# File lib/asana/http_client/error_handling.rb, line 80
def not_found(response)
  NotFound.new.tap { |exception| exception.response = response }
end
payment_required(response) click to toggle source

Internal: Returns a PremiumOnly exception.

# File lib/asana/http_client/error_handling.rb, line 70
def payment_required(response)
  PremiumOnly.new.tap { |exception| exception.response = response }
end
rate_limit_enforced(response) click to toggle source

Internal: Returns a RateLimitEnforced exception with a retry after field.

# File lib/asana/http_client/error_handling.rb, line 86
def rate_limit_enforced(response)
  retry_after_seconds = response[:headers]['Retry-After']
  RateLimitEnforced.new(retry_after_seconds).tap do |exception|
    exception.response = response
  end
end
recover_response(response) click to toggle source
# File lib/asana/http_client/error_handling.rb, line 111
def recover_response(response)
  r = response.dup.tap { |res| res[:body] = body(response) }
  Response.new(OpenStruct.new(env: OpenStruct.new(r)))
end
server_error(response) click to toggle source

Internal: Returns a ServerError exception with a unique phrase.

# File lib/asana/http_client/error_handling.rb, line 94
def server_error(response)
  phrase = body(response).fetch('errors', []).first['phrase']
  ServerError.new(phrase).tap do |exception|
    exception.response = response
  end
end