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.


109
110
111
# File 'lib/asana/http_client/error_handling.rb', line 109

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.


114
115
116
# File 'lib/asana/http_client/error_handling.rb', line 114

def body(response)
  MultiJson.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.


82
83
84
# File 'lib/asana/http_client/error_handling.rb', line 82

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:


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
58
59
# File 'lib/asana/http_client/error_handling.rb', line 31

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.


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

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.


72
73
74
# File 'lib/asana/http_client/error_handling.rb', line 72

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.


87
88
89
# File 'lib/asana/http_client/error_handling.rb', line 87

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.


77
78
79
# File 'lib/asana/http_client/error_handling.rb', line 77

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.


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

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.


118
119
120
121
# File 'lib/asana/http_client/error_handling.rb', line 118

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.


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

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