asana 0.10.3 → 2.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/build.yml +24 -0
- data/.github/workflows/pubilsh-to-rubygem.yml +18 -0
- data/.github/workflows/publish-to-github-releases.yml +16 -0
- data/.gitignore +0 -1
- data/.rubocop.yml +38 -3
- data/.ruby-version +1 -1
- data/Appraisals +8 -3
- data/Gemfile +7 -3
- data/Gemfile.lock +166 -0
- data/Guardfile +12 -10
- data/README.md +45 -20
- data/Rakefile +20 -27
- data/VERSION +1 -1
- data/asana.gemspec +20 -18
- data/examples/Gemfile.lock +2 -2
- data/examples/cli_app.rb +2 -2
- data/examples/events.rb +3 -3
- data/examples/personal_access_token.rb +2 -2
- data/lib/asana/authentication/oauth2/access_token_authentication.rb +4 -1
- data/lib/asana/authentication/oauth2/bearer_token_authentication.rb +3 -2
- data/lib/asana/authentication/oauth2/client.rb +2 -0
- data/lib/asana/authentication/oauth2.rb +6 -4
- data/lib/asana/authentication/token_authentication.rb +3 -1
- data/lib/asana/authentication.rb +2 -0
- data/lib/asana/client/configuration.rb +6 -5
- data/lib/asana/client.rb +13 -11
- data/lib/asana/errors.rb +16 -11
- data/lib/asana/http_client/environment_info.rb +9 -8
- data/lib/asana/http_client/error_handling.rb +26 -20
- data/lib/asana/http_client/response.rb +2 -0
- data/lib/asana/http_client.rb +66 -65
- data/lib/asana/resource_includes/attachment_uploading.rb +6 -6
- data/lib/asana/resource_includes/collection.rb +4 -4
- data/lib/asana/resource_includes/event.rb +2 -0
- data/lib/asana/resource_includes/event_subscription.rb +2 -0
- data/lib/asana/resource_includes/events.rb +4 -1
- data/lib/asana/resource_includes/registry.rb +2 -0
- data/lib/asana/resource_includes/resource.rb +8 -5
- data/lib/asana/resource_includes/response_helper.rb +2 -0
- data/lib/asana/resources/audit_log_api.rb +42 -0
- data/lib/asana/resources/gen/attachments_base.rb +7 -6
- data/lib/asana/resources/gen/audit_log_api_base.rb +37 -0
- data/lib/asana/resources/gen/goal_relationships_base.rb +83 -0
- data/lib/asana/resources/gen/goals_base.rb +153 -0
- data/lib/asana/resources/gen/memberships_base.rb +71 -0
- data/lib/asana/resources/gen/portfolios_base.rb +3 -3
- data/lib/asana/resources/gen/project_briefs_base.rb +68 -0
- data/lib/asana/resources/gen/project_templates_base.rb +73 -0
- data/lib/asana/resources/gen/projects_base.rb +17 -4
- data/lib/asana/resources/gen/status_updates_base.rb +72 -0
- data/lib/asana/resources/gen/tasks_base.rb +13 -15
- data/lib/asana/resources/gen/teams_base.rb +41 -13
- data/lib/asana/resources/gen/time_periods_base.rb +47 -0
- data/lib/asana/resources/gen/typeahead_base.rb +2 -2
- data/lib/asana/resources/gen/users_base.rb +3 -4
- data/lib/asana/resources/gen/webhooks_base.rb +13 -0
- data/lib/asana/resources/gen/workspaces_base.rb +1 -1
- data/lib/asana/resources/goal.rb +54 -0
- data/lib/asana/resources/goal_relationship.rb +32 -0
- data/lib/asana/resources/membership.rb +20 -0
- data/lib/asana/resources/portfolio.rb +3 -3
- data/lib/asana/resources/project_brief.rb +30 -0
- data/lib/asana/resources/project_template.rb +36 -0
- data/lib/asana/resources/status_update.rb +54 -0
- data/lib/asana/resources/time_period.rb +30 -0
- data/lib/asana/resources/typeahead.rb +1 -1
- data/lib/asana/resources.rb +4 -4
- data/lib/asana/ruby2_0_0_compatibility.rb +2 -0
- data/lib/asana/version.rb +1 -1
- data/lib/asana.rb +2 -0
- data/package-lock.json +115 -0
- data/samples/attachments_sample.yaml +4 -4
- data/samples/audit_log_api_sample.yaml +11 -0
- data/samples/goal_relationships_sample.yaml +51 -0
- data/samples/goals_sample.yaml +101 -0
- data/samples/memberships_sample.yaml +41 -0
- data/samples/project_briefs_sample.yaml +41 -0
- data/samples/project_templates_sample.yaml +41 -0
- data/samples/projects_sample.yaml +10 -0
- data/samples/status_updates_sample.yaml +41 -0
- data/samples/teams_sample.yaml +24 -4
- data/samples/time_periods_sample.yaml +21 -0
- data/samples/webhooks_sample.yaml +10 -0
- metadata +75 -40
- data/.travis.yml +0 -16
data/asana.gemspec
CHANGED
@@ -1,32 +1,34 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
5
|
require 'asana/version'
|
5
6
|
|
6
7
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
8
|
+
spec.name = 'asana'
|
8
9
|
spec.version = Asana::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
10
|
+
spec.authors = ['Txus']
|
11
|
+
spec.email = ['me@txus.io']
|
11
12
|
|
12
|
-
spec.summary =
|
13
|
-
spec.description =
|
14
|
-
spec.homepage =
|
15
|
-
spec.license =
|
13
|
+
spec.summary = 'Official Ruby client for the Asana API'
|
14
|
+
spec.description = 'Official Ruby client for the Asana API'
|
15
|
+
spec.homepage = 'https://github.com/asana/ruby-asana'
|
16
|
+
spec.license = 'MIT'
|
16
17
|
|
17
18
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
|
-
spec.bindir =
|
19
|
+
spec.bindir = 'exe'
|
19
20
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
|
-
spec.require_paths = [
|
21
|
+
spec.require_paths = ['lib']
|
21
22
|
|
22
|
-
spec.required_ruby_version = '
|
23
|
+
spec.required_ruby_version = '>= 2.7'
|
23
24
|
|
24
|
-
spec.add_dependency
|
25
|
-
spec.add_dependency
|
26
|
-
spec.add_dependency
|
27
|
-
spec.add_dependency
|
25
|
+
spec.add_dependency 'faraday', '~> 2.0'
|
26
|
+
spec.add_dependency 'faraday-follow_redirects'
|
27
|
+
spec.add_dependency 'faraday-multipart'
|
28
|
+
spec.add_dependency 'oauth2', '>= 1.4', '< 3'
|
28
29
|
|
29
|
-
spec.add_development_dependency "rake", "~> 10.0"
|
30
|
-
spec.add_development_dependency "rspec", "~> 3.2"
|
31
30
|
spec.add_development_dependency 'appraisal', '~> 2.1', '>= 2.1'
|
31
|
+
spec.add_development_dependency 'rake', '~> 13.0'
|
32
|
+
spec.add_development_dependency 'rspec', '~> 3.2'
|
33
|
+
spec.metadata['rubygems_mfa_required'] = 'true'
|
32
34
|
end
|
data/examples/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: ..
|
3
3
|
specs:
|
4
|
-
asana (0.10.
|
4
|
+
asana (0.10.5)
|
5
5
|
faraday (~> 1.0)
|
6
6
|
faraday_middleware (~> 1.0)
|
7
7
|
faraday_middleware-multi_json (~> 0.0)
|
@@ -27,7 +27,7 @@ GEM
|
|
27
27
|
multi_json (~> 1.3)
|
28
28
|
multi_xml (~> 0.5)
|
29
29
|
rack (>= 1.2, < 3)
|
30
|
-
rack (2.2.3)
|
30
|
+
rack (2.2.3.1)
|
31
31
|
|
32
32
|
PLATFORMS
|
33
33
|
ruby
|
data/examples/cli_app.rb
CHANGED
@@ -17,9 +17,9 @@ client = Asana::Client.new do |c|
|
|
17
17
|
end
|
18
18
|
|
19
19
|
puts "My Workspaces:"
|
20
|
-
client.workspaces.
|
20
|
+
client.workspaces.get_workspaces.each do |workspace|
|
21
21
|
puts "\t* #{workspace.name} - tags:"
|
22
|
-
client.tags.
|
22
|
+
client.tags.get_tags_for_workspace(workspace: workspace.id).each do |tag|
|
23
23
|
puts "\t\t- #{tag.name}"
|
24
24
|
end
|
25
25
|
end
|
data/examples/events.rb
CHANGED
@@ -13,10 +13,10 @@ client = Asana::Client.new do |c|
|
|
13
13
|
c.authentication :access_token, access_token
|
14
14
|
end
|
15
15
|
|
16
|
-
workspace = client.workspaces.
|
17
|
-
task = client.tasks.
|
16
|
+
workspace = client.workspaces.get_workspaces.first
|
17
|
+
task = client.tasks.get_tasks(assignee: "me", workspace: workspace.id).first
|
18
18
|
unless task
|
19
|
-
task = client.tasks.
|
19
|
+
task = client.tasks.create_task(workspace: workspace.id, name: "Hello world!", assignee: "me")
|
20
20
|
end
|
21
21
|
|
22
22
|
Thread.abort_on_exception = true
|
@@ -13,9 +13,9 @@ client = Asana::Client.new do |c|
|
|
13
13
|
end
|
14
14
|
|
15
15
|
puts "My Workspaces:"
|
16
|
-
client.workspaces.
|
16
|
+
client.workspaces.get_workspaces.each do |workspace|
|
17
17
|
puts "\t* #{workspace.name} - tags:"
|
18
|
-
client.tags.
|
18
|
+
client.tags.get_tags_for_workspace(workspace: workspace.id).each do |tag|
|
19
19
|
puts "\t\t- #{tag.name}"
|
20
20
|
end
|
21
21
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Asana
|
2
4
|
module Authentication
|
3
5
|
module OAuth2
|
@@ -43,7 +45,8 @@ module Asana
|
|
43
45
|
# Returns nothing.
|
44
46
|
def configure(connection)
|
45
47
|
@token = @token.refresh! if @token.expired?
|
46
|
-
|
48
|
+
|
49
|
+
connection.request :authorization, 'Bearer', @token.token
|
47
50
|
end
|
48
51
|
end
|
49
52
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Asana
|
2
4
|
module Authentication
|
3
5
|
module OAuth2
|
@@ -24,8 +26,7 @@ module Asana
|
|
24
26
|
#
|
25
27
|
# Returns nothing.
|
26
28
|
def configure(connection)
|
27
|
-
connection.authorization
|
28
|
-
connection.request :oauth2, token_type: 'bearer'
|
29
|
+
connection.request :authorization, 'Bearer', @token
|
29
30
|
end
|
30
31
|
end
|
31
32
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative 'oauth2/bearer_token_authentication'
|
2
4
|
require_relative 'oauth2/access_token_authentication'
|
3
5
|
require_relative 'oauth2/client'
|
@@ -31,10 +33,10 @@ module Asana
|
|
31
33
|
client = Client.new(client_id: client_id,
|
32
34
|
client_secret: client_secret,
|
33
35
|
redirect_uri: 'urn:ietf:wg:oauth:2.0:oob')
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
auth_code =
|
36
|
+
$stdout.puts '1. Go to the following URL to authorize the ' \
|
37
|
+
"application: #{client.authorize_url}"
|
38
|
+
$stdout.puts '2. Paste the authorization code here: '
|
39
|
+
auth_code = $stdin.gets.chomp
|
38
40
|
client.token_from_auth_code(auth_code)
|
39
41
|
end
|
40
42
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Asana
|
2
4
|
module Authentication
|
3
5
|
# Public: Represents an API token authentication mechanism.
|
@@ -13,7 +15,7 @@ module Asana
|
|
13
15
|
#
|
14
16
|
# Returns nothing.
|
15
17
|
def configure(connection)
|
16
|
-
connection.
|
18
|
+
connection.request :authorization, :basic, @token, ''
|
17
19
|
end
|
18
20
|
end
|
19
21
|
end
|
data/lib/asana/authentication.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Asana
|
2
4
|
class Client
|
3
5
|
# Internal: Represents a configuration DSL for an Asana::Client.
|
@@ -17,7 +19,7 @@ module Asana
|
|
17
19
|
# Public: Initializes an empty configuration object.
|
18
20
|
def initialize
|
19
21
|
@configuration = {
|
20
|
-
|
22
|
+
log_asana_change_warnings: true
|
21
23
|
}
|
22
24
|
end
|
23
25
|
|
@@ -100,7 +102,6 @@ module Asana
|
|
100
102
|
#
|
101
103
|
# Raises ArgumentError if the OAuth2 configuration arguments are invalid.
|
102
104
|
#
|
103
|
-
# rubocop:disable Metrics/MethodLength
|
104
105
|
def oauth2(value)
|
105
106
|
case value
|
106
107
|
when ::OAuth2::AccessToken
|
@@ -111,8 +112,8 @@ module Asana
|
|
111
112
|
from_bearer_token(value[:bearer_token])
|
112
113
|
else
|
113
114
|
error 'Invalid OAuth2 configuration: pass in either an ' \
|
114
|
-
|
115
|
-
|
115
|
+
'::OAuth2::AccessToken object of your own or a hash ' \
|
116
|
+
'containing :refresh_token or :bearer_token.'
|
116
117
|
end
|
117
118
|
end
|
118
119
|
|
@@ -158,7 +159,7 @@ module Asana
|
|
158
159
|
end
|
159
160
|
|
160
161
|
def requiring(hash, *keys)
|
161
|
-
missing_keys = keys.
|
162
|
+
missing_keys = keys.reject { |k| hash.key?(k) }
|
162
163
|
missing_keys.any? && error("Missing keys: #{missing_keys.join(', ')}")
|
163
164
|
keys.map { |k| hash[k] }
|
164
165
|
end
|
data/lib/asana/client.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative 'authentication'
|
2
4
|
require_relative 'client/configuration'
|
3
5
|
require_relative 'resources'
|
@@ -59,12 +61,12 @@ module Asana
|
|
59
61
|
@resource = resource
|
60
62
|
end
|
61
63
|
|
62
|
-
def method_missing(
|
63
|
-
@resource.public_send(
|
64
|
+
def method_missing(method_name, *args, **kwargs, &block)
|
65
|
+
@resource.public_send(method_name, *([@client] + args), **kwargs, &block)
|
64
66
|
end
|
65
67
|
|
66
|
-
def respond_to_missing?(
|
67
|
-
@resource.respond_to?(
|
68
|
+
def respond_to_missing?(method_name, *)
|
69
|
+
@resource.respond_to?(method_name)
|
68
70
|
end
|
69
71
|
end
|
70
72
|
|
@@ -72,15 +74,15 @@ module Asana
|
|
72
74
|
#
|
73
75
|
# Yields a {Asana::Client::Configuration} object as a configuration
|
74
76
|
# DSL. See {Asana::Client} for usage examples.
|
75
|
-
def initialize
|
76
|
-
config = Configuration.new.tap
|
77
|
+
def initialize(&block)
|
78
|
+
config = Configuration.new.tap(&block).to_h
|
77
79
|
@http_client =
|
78
|
-
HttpClient.new(authentication:
|
79
|
-
adapter:
|
80
|
-
user_agent:
|
81
|
-
debug_mode:
|
80
|
+
HttpClient.new(authentication: config.fetch(:authentication),
|
81
|
+
adapter: config[:faraday_adapter],
|
82
|
+
user_agent: config[:user_agent],
|
83
|
+
debug_mode: config[:debug_mode],
|
82
84
|
log_asana_change_warnings: config[:log_asana_change_warnings],
|
83
|
-
default_headers:
|
85
|
+
default_headers: config[:default_headers],
|
84
86
|
&config[:faraday_configuration])
|
85
87
|
end
|
86
88
|
|
data/lib/asana/errors.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Asana
|
2
4
|
# Public: Defines the different errors that the Asana API may throw, which the
|
3
5
|
# client code may want to catch.
|
@@ -19,8 +21,8 @@ module Asana
|
|
19
21
|
# user could not be authenticated.
|
20
22
|
NotAuthorized = Class.new(APIError) do
|
21
23
|
def to_s
|
22
|
-
'Valid credentials were not provided with the request, so the API could '\
|
23
|
-
|
24
|
+
'Valid credentials were not provided with the request, so the API could ' \
|
25
|
+
'not associate a user with the request.'
|
24
26
|
end
|
25
27
|
end
|
26
28
|
|
@@ -28,8 +30,8 @@ module Asana
|
|
28
30
|
# that requires a premium account (Payment Required).
|
29
31
|
PremiumOnly = Class.new(APIError) do
|
30
32
|
def to_s
|
31
|
-
'The endpoint that is being requested is only available to premium '\
|
32
|
-
|
33
|
+
'The endpoint that is being requested is only available to premium ' \
|
34
|
+
'users.'
|
33
35
|
end
|
34
36
|
end
|
35
37
|
|
@@ -37,18 +39,18 @@ module Asana
|
|
37
39
|
# access the requested resource or to perform the requested action on it.
|
38
40
|
Forbidden = Class.new(APIError) do
|
39
41
|
def to_s
|
40
|
-
'The authorization and request syntax was valid but the server is refusing '\
|
41
|
-
|
42
|
-
|
42
|
+
'The authorization and request syntax was valid but the server is refusing ' \
|
43
|
+
'to complete the request. This can happen if you try to read or write ' \
|
44
|
+
'to objects or properties that the user does not have access to.'
|
43
45
|
end
|
44
46
|
end
|
45
47
|
|
46
48
|
# Public: A 404 error. Raised when the requested resource doesn't exist.
|
47
49
|
NotFound = Class.new(APIError) do
|
48
50
|
def to_s
|
49
|
-
'Either the request method and path supplied do not specify a known '\
|
50
|
-
|
51
|
-
|
51
|
+
'Either the request method and path supplied do not specify a known ' \
|
52
|
+
'action in the API, or the object specified by the request does not ' \
|
53
|
+
'exist.'
|
52
54
|
end
|
53
55
|
end
|
54
56
|
|
@@ -59,11 +61,12 @@ module Asana
|
|
59
61
|
attr_accessor :phrase
|
60
62
|
|
61
63
|
def initialize(phrase)
|
64
|
+
super()
|
62
65
|
@phrase = phrase
|
63
66
|
end
|
64
67
|
|
65
68
|
def to_s
|
66
|
-
"There has been an error on Asana's end. Use this unique phrase to "\
|
69
|
+
"There has been an error on Asana's end. Use this unique phrase to " \
|
67
70
|
'identify the problem when contacting support: ' + %("#{@phrase}")
|
68
71
|
end
|
69
72
|
end
|
@@ -74,6 +77,7 @@ module Asana
|
|
74
77
|
attr_accessor :errors
|
75
78
|
|
76
79
|
def initialize(errors)
|
80
|
+
super()
|
77
81
|
@errors = errors
|
78
82
|
end
|
79
83
|
|
@@ -89,6 +93,7 @@ module Asana
|
|
89
93
|
attr_accessor :retry_after_seconds
|
90
94
|
|
91
95
|
def initialize(retry_after_seconds)
|
96
|
+
super()
|
92
97
|
@retry_after_seconds = retry_after_seconds
|
93
98
|
end
|
94
99
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative '../version'
|
2
4
|
require 'openssl'
|
3
5
|
|
@@ -6,7 +8,7 @@ module Asana
|
|
6
8
|
# Internal: Adds environment information to a Faraday request.
|
7
9
|
class EnvironmentInfo
|
8
10
|
# Internal: The default user agent to use in all requests to the API.
|
9
|
-
USER_AGENT = "ruby-asana v#{Asana::VERSION}"
|
11
|
+
USER_AGENT = "ruby-asana v#{Asana::VERSION}"
|
10
12
|
|
11
13
|
def initialize(user_agent = nil)
|
12
14
|
@user_agent = user_agent || USER_AGENT
|
@@ -19,7 +21,7 @@ module Asana
|
|
19
21
|
# environment.
|
20
22
|
def configure(builder)
|
21
23
|
builder.headers[:user_agent] = @user_agent
|
22
|
-
builder.headers[:
|
24
|
+
builder.headers[:'X-Asana-Client-Lib'] = header
|
23
25
|
end
|
24
26
|
|
25
27
|
private
|
@@ -33,21 +35,20 @@ module Asana
|
|
33
35
|
.map { |k, v| "#{k}=#{v}" }.join('&')
|
34
36
|
end
|
35
37
|
|
36
|
-
# rubocop:disable Metrics/MethodLength
|
37
38
|
def os
|
38
|
-
|
39
|
+
case RUBY_PLATFORM
|
40
|
+
when /win32/, /mingw/
|
39
41
|
'windows'
|
40
|
-
|
42
|
+
when /linux/
|
41
43
|
'linux'
|
42
|
-
|
44
|
+
when /darwin/
|
43
45
|
'darwin'
|
44
|
-
|
46
|
+
when /freebsd/
|
45
47
|
'freebsd'
|
46
48
|
else
|
47
49
|
'unknown'
|
48
50
|
end
|
49
51
|
end
|
50
|
-
# rubocop:enable Metrics/MethodLength
|
51
52
|
end
|
52
53
|
end
|
53
54
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative '../errors'
|
4
4
|
|
@@ -11,7 +11,7 @@ module Asana
|
|
11
11
|
|
12
12
|
module_function
|
13
13
|
|
14
|
-
|
14
|
+
MAX_RETRIES = 5
|
15
15
|
|
16
16
|
# Public: Perform a request handling any API errors correspondingly.
|
17
17
|
#
|
@@ -27,30 +27,34 @@ module Asana
|
|
27
27
|
# Raises [Asana::Errors::ServerError] when there's a server problem.
|
28
28
|
# Raises [Asana::Errors::APIError] when the API returns an unknown error.
|
29
29
|
#
|
30
|
-
# rubocop:disable
|
31
|
-
def handle(
|
30
|
+
# rubocop:disable Metrics/AbcSize
|
31
|
+
def handle(num_retries = 0, &request)
|
32
32
|
request.call
|
33
33
|
rescue Faraday::ClientError => e
|
34
34
|
raise e unless e.response
|
35
|
+
|
35
36
|
case e.response[:status]
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
37
|
+
when 400 then raise invalid_request(e.response)
|
38
|
+
when 401 then raise not_authorized(e.response)
|
39
|
+
when 402 then raise payment_required(e.response)
|
40
|
+
when 403 then raise forbidden(e.response)
|
41
|
+
when 404 then raise not_found(e.response)
|
42
|
+
when 412 then recover_response(e.response)
|
43
|
+
when 429 then raise rate_limit_enforced(e.response)
|
44
|
+
when 500 then raise server_error(e.response)
|
45
|
+
else raise api_error(e.response)
|
45
46
|
end
|
47
|
+
# Retry for timeouts or 500s from Asana
|
48
|
+
rescue Faraday::ServerError => e
|
49
|
+
raise server_error(e.response) unless num_retries < MAX_RETRIES
|
50
|
+
|
51
|
+
handle(num_retries + 1, &request)
|
46
52
|
rescue Net::ReadTimeout => e
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
raise e
|
51
|
-
end
|
53
|
+
raise e unless num_retries < MAX_RETRIES
|
54
|
+
|
55
|
+
handle(num_retries + 1, &request)
|
52
56
|
end
|
53
|
-
# rubocop:enable
|
57
|
+
# rubocop:enable Metrics/AbcSize
|
54
58
|
|
55
59
|
# Internal: Returns an InvalidRequest exception including a list of
|
56
60
|
# errors.
|
@@ -105,13 +109,15 @@ module Asana
|
|
105
109
|
|
106
110
|
# Internal: Parser a response body from JSON.
|
107
111
|
def body(response)
|
108
|
-
|
112
|
+
JSON.parse(response[:body])
|
109
113
|
end
|
110
114
|
|
115
|
+
# rubocop:disable Style/OpenStructUse
|
111
116
|
def recover_response(response)
|
112
117
|
r = response.dup.tap { |res| res[:body] = body(response) }
|
113
118
|
Response.new(OpenStruct.new(env: OpenStruct.new(r)))
|
114
119
|
end
|
120
|
+
# rubocop:enable Style/OpenStructUse
|
115
121
|
end
|
116
122
|
end
|
117
123
|
end
|