Module: Asana::HttpClient::ErrorHandling Private

Includes:
Errors
Defined in:
lib/asana/http_client/error_handling.rb

Overview

This module is part of a private API. You should avoid using this module if possible, as it may be removed or be changed in the future.

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

Constant Summary collapse

MAX_RETRIES =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

5

Constants included from Errors

Errors::APIError, Errors::Forbidden, Errors::InvalidRequest, Errors::NotAuthorized, Errors::NotFound, Errors::PremiumOnly, Errors::RateLimitEnforced, Errors::ServerError

Class Method Summary collapse

Class Method Details

.api_error(response) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns an APIError exception.



107
108
109
# File 'lib/asana/http_client/error_handling.rb', line 107

def api_error(response)
  APIError.new.tap { |exception| exception.response = response }
end

.body(response) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Parser a response body from JSON.



112
113
114
# File 'lib/asana/http_client/error_handling.rb', line 112

def body(response)
  JSON.load(response[:body])
end

.forbidden(response) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a Forbidden exception.



80
81
82
# File 'lib/asana/http_client/error_handling.rb', line 80

def forbidden(response)
  Forbidden.new.tap { |exception| exception.response = response }
end

.handle(num_retries = 0, &request) ⇒ Faraday::Response

Perform a request handling any API errors correspondingly.

Parameters:

  • request (Proc)

    a block that will execute the request.

Returns:

  • (Faraday::Response)

    Returns a Faraday::Response object.

Raises:



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/asana/http_client/error_handling.rb', line 29

def handle(num_retries=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
# Retry for timeouts or 500s from Asana
rescue Faraday::ServerError => e
  if num_retries < MAX_RETRIES
    handle(num_retries + 1, &request)
  else
    raise server_error(e.response)
  end
rescue Net::ReadTimeout => e
  if num_retries < MAX_RETRIES
    handle(num_retries + 1, &request)
  else
    raise e
  end
end

.invalid_request(response) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns an InvalidRequest exception including a list of errors.



62
63
64
65
66
67
# File 'lib/asana/http_client/error_handling.rb', line 62

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) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a NotAuthorized exception.



70
71
72
# File 'lib/asana/http_client/error_handling.rb', line 70

def not_authorized(response)
  NotAuthorized.new.tap { |exception| exception.response = response }
end

.not_found(response) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a NotFound exception.



85
86
87
# File 'lib/asana/http_client/error_handling.rb', line 85

def not_found(response)
  NotFound.new.tap { |exception| exception.response = response }
end

.payment_required(response) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a PremiumOnly exception.



75
76
77
# File 'lib/asana/http_client/error_handling.rb', line 75

def payment_required(response)
  PremiumOnly.new.tap { |exception| exception.response = response }
end

.rate_limit_enforced(response) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a RateLimitEnforced exception with a retry after field.



91
92
93
94
95
96
# File 'lib/asana/http_client/error_handling.rb', line 91

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) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



116
117
118
119
# File 'lib/asana/http_client/error_handling.rb', line 116

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) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a ServerError exception with a unique phrase.



99
100
101
102
103
104
# File 'lib/asana/http_client/error_handling.rb', line 99

def server_error(response)
  phrase = body(response).fetch('errors', []).first['phrase']
  ServerError.new(phrase).tap do |exception|
    exception.response = response
  end
end