my_api_client 0.15.0 → 0.19.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (147) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +169 -95
  3. data/.dependabot/config.yml +2 -5
  4. data/.rubocop.yml +5 -1
  5. data/.rubocop_challenge.yml +1 -0
  6. data/.rubocop_todo.yml +53 -1
  7. data/CHANGELOG.md +171 -0
  8. data/Gemfile +0 -3
  9. data/Gemfile.lock +70 -64
  10. data/README.jp.md +97 -24
  11. data/bin/console +4 -0
  12. data/example/api_clients/application_api_client.rb +2 -10
  13. data/example/api_clients/my_rest_api_client.rb +9 -3
  14. data/gemfiles/{rails_4.2.gemfile → rails_6.1.gemfile} +1 -1
  15. data/lib/generators/rails/USAGE +1 -1
  16. data/lib/generators/rails/api_client_generator.rb +6 -0
  17. data/lib/generators/rails/templates/api_client.rb.erb +1 -1
  18. data/lib/generators/rails/templates/application_api_client.rb.erb +0 -11
  19. data/lib/generators/rspec/USAGE +1 -1
  20. data/lib/generators/rspec/api_client_generator.rb +6 -0
  21. data/lib/generators/rspec/templates/api_client_spec.rb.erb +23 -16
  22. data/lib/my_api_client.rb +5 -0
  23. data/lib/my_api_client/base.rb +4 -9
  24. data/lib/my_api_client/default_error_handlers.rb +64 -0
  25. data/lib/my_api_client/error_handling.rb +3 -4
  26. data/lib/my_api_client/error_handling/generator.rb +23 -7
  27. data/lib/my_api_client/errors.rb +1 -53
  28. data/lib/my_api_client/errors/api_limit_error.rb +6 -0
  29. data/lib/my_api_client/errors/client_error.rb +93 -0
  30. data/lib/my_api_client/errors/network_error.rb +43 -0
  31. data/lib/my_api_client/errors/server_error.rb +42 -0
  32. data/lib/my_api_client/params/params.rb +1 -3
  33. data/lib/my_api_client/request.rb +2 -2
  34. data/lib/my_api_client/request/basic.rb +1 -3
  35. data/lib/my_api_client/request/executor.rb +1 -1
  36. data/lib/my_api_client/version.rb +1 -1
  37. data/my_api/Gemfile.lock +89 -87
  38. data/my_api/app/controllers/pagination_controller.rb +1 -1
  39. data/my_api/spec/controllers/rest_controller_spec.rb +23 -5
  40. data/my_api_client.gemspec +2 -2
  41. data/rails_app/rails_5.2/.rspec +3 -0
  42. data/rails_app/rails_5.2/Gemfile +17 -0
  43. data/rails_app/rails_5.2/Gemfile.lock +174 -0
  44. data/rails_app/rails_5.2/README.md +24 -0
  45. data/rails_app/rails_5.2/Rakefile +8 -0
  46. data/rails_app/rails_5.2/app/controllers/application_controller.rb +4 -0
  47. data/rails_app/rails_5.2/app/jobs/application_job.rb +4 -0
  48. data/rails_app/rails_5.2/bin/bundle +5 -0
  49. data/rails_app/rails_5.2/bin/rails +6 -0
  50. data/rails_app/rails_5.2/bin/rake +6 -0
  51. data/rails_app/rails_5.2/bin/setup +27 -0
  52. data/rails_app/rails_5.2/bin/update +27 -0
  53. data/rails_app/rails_5.2/config.ru +7 -0
  54. data/rails_app/rails_5.2/config/application.rb +37 -0
  55. data/rails_app/rails_5.2/config/boot.rb +6 -0
  56. data/rails_app/rails_5.2/config/credentials.yml.enc +1 -0
  57. data/rails_app/rails_5.2/config/environment.rb +7 -0
  58. data/rails_app/rails_5.2/config/environments/development.rb +41 -0
  59. data/rails_app/rails_5.2/config/environments/production.rb +70 -0
  60. data/rails_app/rails_5.2/config/environments/test.rb +38 -0
  61. data/rails_app/rails_5.2/config/initializers/application_controller_renderer.rb +9 -0
  62. data/rails_app/rails_5.2/config/initializers/backtrace_silencers.rb +8 -0
  63. data/rails_app/rails_5.2/config/initializers/cors.rb +17 -0
  64. data/rails_app/rails_5.2/config/initializers/filter_parameter_logging.rb +6 -0
  65. data/rails_app/rails_5.2/config/initializers/inflections.rb +17 -0
  66. data/rails_app/rails_5.2/config/initializers/mime_types.rb +5 -0
  67. data/rails_app/rails_5.2/config/initializers/wrap_parameters.rb +11 -0
  68. data/rails_app/rails_5.2/config/locales/en.yml +33 -0
  69. data/rails_app/rails_5.2/config/routes.rb +5 -0
  70. data/rails_app/rails_5.2/config/spring.rb +8 -0
  71. data/rails_app/rails_5.2/public/robots.txt +1 -0
  72. data/rails_app/rails_5.2/spec/rails_helper.rb +14 -0
  73. data/rails_app/rails_5.2/spec/spec_helper.rb +13 -0
  74. data/rails_app/rails_6.0/.rspec +3 -0
  75. data/rails_app/rails_6.0/Gemfile +17 -0
  76. data/rails_app/rails_6.0/Gemfile.lock +190 -0
  77. data/rails_app/rails_6.0/README.md +24 -0
  78. data/rails_app/rails_6.0/Rakefile +8 -0
  79. data/rails_app/rails_6.0/app/controllers/application_controller.rb +4 -0
  80. data/rails_app/rails_6.0/app/jobs/application_job.rb +9 -0
  81. data/rails_app/rails_6.0/bin/rails +6 -0
  82. data/rails_app/rails_6.0/bin/rake +6 -0
  83. data/rails_app/rails_6.0/bin/setup +27 -0
  84. data/rails_app/rails_6.0/config.ru +7 -0
  85. data/rails_app/rails_6.0/config/application.rb +39 -0
  86. data/rails_app/rails_6.0/config/boot.rb +6 -0
  87. data/rails_app/rails_6.0/config/credentials.yml.enc +1 -0
  88. data/rails_app/rails_6.0/config/environment.rb +7 -0
  89. data/rails_app/rails_6.0/config/environments/development.rb +39 -0
  90. data/rails_app/rails_6.0/config/environments/production.rb +90 -0
  91. data/rails_app/rails_6.0/config/environments/test.rb +41 -0
  92. data/rails_app/rails_6.0/config/initializers/application_controller_renderer.rb +9 -0
  93. data/rails_app/rails_6.0/config/initializers/backtrace_silencers.rb +8 -0
  94. data/rails_app/rails_6.0/config/initializers/cors.rb +17 -0
  95. data/rails_app/rails_6.0/config/initializers/filter_parameter_logging.rb +6 -0
  96. data/rails_app/rails_6.0/config/initializers/inflections.rb +17 -0
  97. data/rails_app/rails_6.0/config/initializers/mime_types.rb +5 -0
  98. data/rails_app/rails_6.0/config/initializers/wrap_parameters.rb +11 -0
  99. data/rails_app/rails_6.0/config/locales/en.yml +33 -0
  100. data/rails_app/rails_6.0/config/routes.rb +5 -0
  101. data/rails_app/rails_6.0/config/spring.rb +8 -0
  102. data/rails_app/rails_6.0/public/robots.txt +1 -0
  103. data/rails_app/rails_6.0/spec/rails_helper.rb +14 -0
  104. data/rails_app/rails_6.0/spec/spec_helper.rb +13 -0
  105. data/rails_app/rails_6.1/.gitattributes +8 -0
  106. data/rails_app/rails_6.1/.gitignore +28 -0
  107. data/rails_app/rails_6.1/.rspec +3 -0
  108. data/rails_app/rails_6.1/Gemfile +17 -0
  109. data/rails_app/rails_6.1/Gemfile.lock +197 -0
  110. data/rails_app/rails_6.1/README.md +24 -0
  111. data/rails_app/rails_6.1/Rakefile +6 -0
  112. data/rails_app/rails_6.1/app/controllers/application_controller.rb +4 -0
  113. data/rails_app/rails_6.1/app/controllers/concerns/.keep +0 -0
  114. data/rails_app/rails_6.1/app/javascript/.keep +0 -0
  115. data/rails_app/rails_6.1/app/models/application_record.rb +5 -0
  116. data/rails_app/rails_6.1/app/models/concerns/.keep +0 -0
  117. data/rails_app/rails_6.1/bin/bundle +114 -0
  118. data/rails_app/rails_6.1/bin/rails +4 -0
  119. data/rails_app/rails_6.1/bin/rake +4 -0
  120. data/rails_app/rails_6.1/bin/setup +33 -0
  121. data/rails_app/rails_6.1/config.ru +6 -0
  122. data/rails_app/rails_6.1/config/application.rb +42 -0
  123. data/rails_app/rails_6.1/config/boot.rb +5 -0
  124. data/rails_app/rails_6.1/config/credentials.yml.enc +1 -0
  125. data/rails_app/rails_6.1/config/database.yml +25 -0
  126. data/rails_app/rails_6.1/config/environment.rb +7 -0
  127. data/rails_app/rails_6.1/config/environments/development.rb +59 -0
  128. data/rails_app/rails_6.1/config/environments/production.rb +97 -0
  129. data/rails_app/rails_6.1/config/environments/test.rb +51 -0
  130. data/rails_app/rails_6.1/config/initializers/application_controller_renderer.rb +9 -0
  131. data/rails_app/rails_6.1/config/initializers/backtrace_silencers.rb +10 -0
  132. data/rails_app/rails_6.1/config/initializers/cors.rb +17 -0
  133. data/rails_app/rails_6.1/config/initializers/filter_parameter_logging.rb +8 -0
  134. data/rails_app/rails_6.1/config/initializers/inflections.rb +17 -0
  135. data/rails_app/rails_6.1/config/initializers/mime_types.rb +5 -0
  136. data/rails_app/rails_6.1/config/initializers/wrap_parameters.rb +16 -0
  137. data/rails_app/rails_6.1/config/locales/en.yml +33 -0
  138. data/rails_app/rails_6.1/config/routes.rb +5 -0
  139. data/rails_app/rails_6.1/db/seeds.rb +8 -0
  140. data/rails_app/rails_6.1/lib/tasks/.keep +0 -0
  141. data/rails_app/rails_6.1/public/robots.txt +1 -0
  142. data/rails_app/rails_6.1/spec/rails_helper.rb +14 -0
  143. data/rails_app/rails_6.1/spec/spec_helper.rb +13 -0
  144. data/rails_app/rails_6.1/tmp/.keep +0 -0
  145. data/rails_app/rails_6.1/tmp/pids/.keep +0 -0
  146. data/rails_app/rails_6.1/vendor/.keep +0 -0
  147. metadata +119 -7
@@ -3,6 +3,10 @@
3
3
 
4
4
  require 'bundler/setup'
5
5
  require 'my_api_client'
6
+ require './example/api_clients/my_error_api_client'
7
+ require './example/api_clients/my_rest_api_client'
8
+ require './example/api_clients/my_pagination_api_client'
9
+ require './example/api_clients/my_status_api_client'
6
10
 
7
11
  # You can add fixtures and/or initialization code here to make experimenting
8
12
  # with your gem easier. You can also use a different console, if you like.
@@ -8,14 +8,6 @@ class ApplicationApiClient < MyApiClient::Base
8
8
 
9
9
  self.logger = ::Logger.new(nil)
10
10
 
11
- http_open_timeout 2.seconds
12
- http_read_timeout 3.seconds
13
-
14
- retry_on MyApiClient::NetworkError, wait: 0.seconds, attempts: 3
15
-
16
- error_handling status_code: 400..499, raise: MyApiClient::ClientError
17
- error_handling status_code: 500..599 do |params, logger|
18
- logger.warn 'Server error occurred.'
19
- raise MyApiClient::ServerError, params
20
- end
11
+ http_open_timeout 5.seconds
12
+ http_read_timeout 5.seconds
21
13
  end
@@ -18,13 +18,19 @@ class MyRestApiClient < ApplicationApiClient
18
18
  end
19
19
 
20
20
  # POST rest
21
- def create_post(title:)
21
+ def post_post(title:)
22
22
  body = { title: title }
23
23
  post 'rest', body: body, headers: headers
24
24
  end
25
25
 
26
- # POST/PUT/PATCH rest/:id
27
- def update_post(id:, title:)
26
+ # PUT rest/:id
27
+ def put_post(id:, title:)
28
+ body = { title: title }
29
+ put "rest/#{id}", body: body, headers: headers
30
+ end
31
+
32
+ # PATCH rest/:id
33
+ def patch_post(id:, title:)
28
34
  body = { title: title }
29
35
  patch "rest/#{id}", body: body, headers: headers
30
36
  end
@@ -6,7 +6,7 @@ source 'https://rubygems.org'
6
6
 
7
7
  git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
8
8
 
9
- gem 'activesupport', '~> 4.2.0'
9
+ gem 'activesupport', '~> 6.1.0'
10
10
 
11
11
  group :integrations, optional: true do
12
12
  gem 'bugsnag', '>= 6.11.0'
@@ -2,7 +2,7 @@ Description:
2
2
  Generate a new api client class files.
3
3
 
4
4
  Example:
5
- `rails g api_client path/to/resource get:path/to/resource`
5
+ `rails g api_client path/to/resource get:path/to/resource` --endpoint https://example.com
6
6
 
7
7
  This will create:
8
8
  create app/api_clients/application_api_client.rb
@@ -15,6 +15,12 @@ module Rails
15
15
  default: %w[get:path/to/resource post:path/to/resource],
16
16
  banner: '{method}:{path} {method}:{path}'
17
17
 
18
+ class_option :endpoint,
19
+ type: :string,
20
+ default: 'https://example.com',
21
+ banner: 'https://example.com',
22
+ desc: 'Common part of the target API endpoint'
23
+
18
24
  def generate_root_class
19
25
  file_path = File.join('app/api_clients', 'application_api_client.rb')
20
26
  return if File.exist?(file_path)
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class <%= "#{class_name}ApiClient" %> < ::ApplicationApiClient
4
- endpoint 'https://example.com'
4
+ endpoint '<%= options[:endpoint] %>'
5
5
 
6
6
  # error_handling json: { '$.errors.code': 10 } do |params, logger|
7
7
  # # Behavior when detected an error.
@@ -20,15 +20,4 @@ class ApplicationApiClient < MyApiClient::Base
20
20
  # seconds.
21
21
  #
22
22
  # http_read_timeout 3.seconds
23
-
24
- # Catch the exception and re-execution after any seconds, like as ActiveJob.
25
- # Please note that it is executed as a synchronous process unlike ActiveJob.
26
- #
27
- # retry_on MyApiClient::NetworkError, wait: 5.seconds, attempts: 3
28
-
29
- # Set a HTTP response verifyment and behavior. If conflicting conditions are
30
- # set, the processing defined later takes precedence
31
- #
32
- # error_handling status_code: 400..499, raise: MyApiClient::ClientError
33
- # error_handling status_code: 500..599, raise: MyApiClient::ServerError
34
23
  end
@@ -2,7 +2,7 @@ Description:
2
2
  Generate a new api client spec files.
3
3
 
4
4
  Example:
5
- rails g rspec:api_client path/to/resource get:path/to/resource`
5
+ rails g rspec:api_client path/to/resource get:path/to/resource` --endpoint https://example.com
6
6
 
7
7
  This will create:
8
8
  create spec/api_clients/path/to/resource_api_client_spec.rb
@@ -16,6 +16,12 @@ module Rspec
16
16
  default: %w[get:path/to/resource post:path/to/resource],
17
17
  banner: '{method}:{path} {method}:{path}'
18
18
 
19
+ class_option :endpoint,
20
+ type: :string,
21
+ default: 'https://example.com',
22
+ banner: 'https://example.com',
23
+ desc: 'Common part of the target API endpoint'
24
+
19
25
  class_option :api_client_specs, type: :boolean, default: true
20
26
 
21
27
  def generate_api_client_spec
@@ -11,16 +11,28 @@ RSpec.describe <%= "#{class_name}ApiClient" %>, <%= type_metatag(:api_client) %>
11
11
  end
12
12
 
13
13
  shared_examples 'to handle errors' do
14
- it do
15
- expect { api_request }
16
- .to be_handled_as_an_error(MyApiClient::ClientError)
17
- .when_receive(status_code: 400)
14
+ context 'when the API returns 200 OK' do
15
+ it do
16
+ expect { api_request }
17
+ .not_to be_handled_as_an_error
18
+ .when_receive(status_code: 200)
19
+ end
18
20
  end
19
21
 
20
- it do
21
- expect { api_request }
22
- .to be_handled_as_an_error(MyApiClient::ServerError)
23
- .when_receive(status_code: 500)
22
+ context 'when the API returns 400 Bad Request' do
23
+ it do
24
+ expect { api_request }
25
+ .to be_handled_as_an_error(MyApiClient::ClientError::BadRequest)
26
+ .when_receive(status_code: 400)
27
+ end
28
+ end
29
+
30
+ context 'when the API returns 500 Internal Server Error' do
31
+ it do
32
+ expect { api_request }
33
+ .to be_handled_as_an_error(MyApiClient::ServerError::InternalServerError)
34
+ .when_receive(status_code: 500)
35
+ end
24
36
  end
25
37
  end
26
38
  <% yeild_request_arguments do |action, http_method, pathname| -%>
@@ -28,22 +40,17 @@ RSpec.describe <%= "#{class_name}ApiClient" %>, <%= type_metatag(:api_client) %>
28
40
  describe '#<%= action %>' do
29
41
  subject(:api_request) { api_client.<%= action %> }
30
42
 
43
+ it_behaves_like 'to handle errors'
44
+
31
45
  it do
32
46
  expect { api_request }
33
- .to request_to(:<%= http_method %>, 'https://example.com/<%= pathname %>')
47
+ .to request_to(:<%= http_method %>, '<%= options[:endpoint] %>/<%= pathname %>')
34
48
  <% if http_method == 'get' -%>
35
49
  .with(headers: headers, query: {})
36
50
  <% else -%>
37
51
  .with(headers: headers, body: {})
38
52
  <% end -%>
39
53
  end
40
-
41
- it_behaves_like 'to handle errors' do
42
- it do
43
- expect { api_request }.not_to be_handled_as_an_error
44
- .when_receive(status_code: 200, body: nil, headers: nil)
45
- end
46
- end
47
54
  end
48
55
  <% end -%>
49
56
  end
@@ -19,6 +19,11 @@ require 'my_api_client/request/executor'
19
19
  require 'my_api_client/request/basic'
20
20
  require 'my_api_client/request/pagination'
21
21
  require 'my_api_client/errors'
22
+ require 'my_api_client/errors/api_limit_error'
23
+ require 'my_api_client/errors/client_error'
24
+ require 'my_api_client/errors/network_error'
25
+ require 'my_api_client/errors/server_error'
26
+ require 'my_api_client/default_error_handlers'
22
27
  require 'my_api_client/params/params'
23
28
  require 'my_api_client/params/request'
24
29
  require 'my_api_client/request'
@@ -8,15 +8,10 @@ module MyApiClient
8
8
  include MyApiClient::Exceptions
9
9
  include MyApiClient::Request
10
10
 
11
- if ActiveSupport::VERSION::STRING >= '5.2.0'
12
- class_attribute :logger, instance_writer: false, default: ::Logger.new(STDOUT)
13
- class_attribute :error_handlers, instance_writer: false, default: []
14
- else
15
- class_attribute :logger
16
- class_attribute :error_handlers
17
- self.logger = ::Logger.new(STDOUT)
18
- self.error_handlers = []
19
- end
11
+ class_attribute :logger, instance_writer: false, default: ::Logger.new($stdout)
12
+ class_attribute :error_handlers, instance_writer: false, default: []
13
+
14
+ include MyApiClient::DefaultErrorHandlers
20
15
 
21
16
  # NOTE: This class **MUST NOT** implement #initialize method. Because it
22
17
  # will become constraint that need call #super in the #initialize at
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MyApiClient
4
+ # Provides default error handlers.
5
+ module DefaultErrorHandlers
6
+ extend ActiveSupport::Concern
7
+
8
+ # rubocop:disable Metrics/BlockLength
9
+ included do
10
+ # NOTE: The built-in error handlers are following. Although they are prepared
11
+ # to save the trouble of defining, but you can override any error handlers
12
+ # in your API client class.
13
+ error_handling status_code: 400..499, raise: ClientError
14
+ error_handling status_code: 400, raise: ClientError::BadRequest
15
+ error_handling status_code: 401, raise: ClientError::Unauthorized
16
+ error_handling status_code: 402, raise: ClientError::PaymentRequired
17
+ error_handling status_code: 403, raise: ClientError::Forbidden
18
+ error_handling status_code: 404, raise: ClientError::NotFound
19
+ error_handling status_code: 405, raise: ClientError::MethodNotAllowed
20
+ error_handling status_code: 406, raise: ClientError::NotAcceptable
21
+ error_handling status_code: 407, raise: ClientError::ProxyAuthenticationRequired
22
+ error_handling status_code: 408, raise: ClientError::RequestTimeout
23
+ error_handling status_code: 409, raise: ClientError::Conflict
24
+ error_handling status_code: 410, raise: ClientError::Gone
25
+ error_handling status_code: 411, raise: ClientError::LengthRequired
26
+ error_handling status_code: 412, raise: ClientError::PreconditionFailed
27
+ error_handling status_code: 413, raise: ClientError::RequestEntityTooLarge
28
+ error_handling status_code: 414, raise: ClientError::RequestUriTooLong
29
+ error_handling status_code: 415, raise: ClientError::UnsupportedMediaType
30
+ error_handling status_code: 416, raise: ClientError::RequestedRangeNotSatisfiable
31
+ error_handling status_code: 417, raise: ClientError::ExpectationFailed
32
+ error_handling status_code: 418, raise: ClientError::IamTeapot
33
+ error_handling status_code: 421, raise: ClientError::MisdirectedRequest
34
+ error_handling status_code: 422, raise: ClientError::UnprocessableEntity
35
+ error_handling status_code: 423, raise: ClientError::Locked
36
+ error_handling status_code: 424, raise: ClientError::FailedDependency
37
+ error_handling status_code: 425, raise: ClientError::TooEarly
38
+ error_handling status_code: 426, raise: ClientError::UpgradeRequired
39
+ error_handling status_code: 428, raise: ClientError::PreconditionRequired
40
+ error_handling status_code: 429, raise: ClientError::TooManyRequests
41
+ error_handling status_code: 431, raise: ClientError::RequestHeaderFieldsTooLarge
42
+ error_handling status_code: 451, raise: ClientError::UnavailableForLegalReasons
43
+
44
+ error_handling status_code: 500..599, raise: ServerError
45
+ error_handling status_code: 500, raise: ServerError::InternalServerError
46
+ error_handling status_code: 501, raise: ServerError::NotImplemented
47
+ error_handling status_code: 502, raise: ServerError::BadGateway
48
+ error_handling status_code: 503, raise: ServerError::ServiceUnavailable
49
+ error_handling status_code: 504, raise: ServerError::GatewayTimeout
50
+ error_handling status_code: 505, raise: ServerError::HttpVersionNotSupported
51
+ error_handling status_code: 506, raise: ServerError::VariantAlsoNegotiates
52
+ error_handling status_code: 507, raise: ServerError::InsufficientStorage
53
+ error_handling status_code: 508, raise: ServerError::LoopDetected
54
+ error_handling status_code: 509, raise: ServerError::BandwidthLimitExceeded
55
+ error_handling status_code: 510, raise: ServerError::NotExtended
56
+ error_handling status_code: 511, raise: ServerError::NetworkAuthenticationRequired
57
+
58
+ # Catch the exception and re-execution after any seconds, like as ActiveJob.
59
+ # Please note that it is executed as a synchronous process unlike ActiveJob.
60
+ retry_on NetworkError, wait: 0.3.seconds, attempts: 3
61
+ end
62
+ # rubocop:enable Metrics/BlockLength
63
+ end
64
+ end
@@ -9,9 +9,8 @@ module MyApiClient
9
9
  # @example
10
10
  # error_handling status_code: 200, json: :forbid_nil
11
11
  # error_handling status_code: 400..499, raise: MyApiClient::ClientError
12
- # error_handling status_code: 500..599 do |params, logger|
12
+ # error_handling status_code: 500..599, raise: MyApiClient::ServerError do |params, logger|
13
13
  # logger.warn 'Server error occurred.'
14
- # raise MyApiClient::ServerError, params
15
14
  # end
16
15
  #
17
16
  # error_handling json: { '$.errors.code': 10..19 }, with: :my_error_handling
@@ -33,7 +32,7 @@ module MyApiClient
33
32
  # as JsonPath expression.
34
33
  # If specified `:forbid_nil`, it forbid `nil` at the response body.
35
34
  # @option with [Symbol]
36
- # Calls specified method when error detected
35
+ # Calls specified method before raising exception when error detected.
37
36
  # @option raise [MyApiClient::Error]
38
37
  # Raises specified error when an invalid response detected.
39
38
  # Should be inherited `MyApiClient::Error` class.
@@ -42,7 +41,7 @@ module MyApiClient
42
41
  # If the error detected, retries the API request. Requires `raise` option.
43
42
  # You can set `true` or `retry_on` options (`wait` and `attempts`).
44
43
  # @yield [MyApiClient::Params::Params, MyApiClient::Request::Logger]
45
- # Executes the block when error detected.
44
+ # Executes the block before raising exception when error detected.
46
45
  # Forbid to be used with the` retry` option.
47
46
  def error_handling(**options, &block)
48
47
  options[:block] = block
@@ -23,8 +23,8 @@ module MyApiClient
23
23
  # Raises specified error when error detected. default: MyApiClient::Error
24
24
  # @option block [Proc]
25
25
  # Executes the block when error detected
26
- # @return [Proc]
27
- # Returns value as `Proc`.
26
+ # @return [Proc, nil]
27
+ # Returns the error handler as "Proc". If no error occurs, return `nil`.
28
28
  def initialize(**options)
29
29
  options[:raise] ||= MyApiClient::Error
30
30
  verify_and_set_arguments(**options)
@@ -43,14 +43,32 @@ module MyApiClient
43
43
 
44
44
  def generate_error_handler
45
45
  if _block
46
- ->(params, logger) { _block.call(params, logger) }
46
+ block_caller
47
47
  elsif _with
48
- ->(params, logger) { _instance.send(_with, params, logger) }
48
+ method_caller
49
49
  else
50
- ->(params, _) { raise _raise, params }
50
+ error_raiser
51
51
  end
52
52
  end
53
53
 
54
+ def block_caller
55
+ lambda { |params, logger|
56
+ _block.call(params, logger)
57
+ error_raiser.call(params, logger)
58
+ }
59
+ end
60
+
61
+ def method_caller
62
+ lambda { |params, logger|
63
+ _instance.send(_with, params, logger)
64
+ error_raiser.call(params, logger)
65
+ }
66
+ end
67
+
68
+ def error_raiser
69
+ ->(params, _) { raise _raise, params }
70
+ end
71
+
54
72
  # Verify given options and raise error if they are incorrect.
55
73
  # If not, set them to instance variables.
56
74
  #
@@ -67,7 +85,6 @@ module MyApiClient
67
85
  end
68
86
  end
69
87
 
70
- # rubocop:disable Metrics/CyclomaticComplexity
71
88
  def match?(operator, target)
72
89
  case operator
73
90
  when nil
@@ -84,7 +101,6 @@ module MyApiClient
84
101
  raise "Unexpected operator type was given: #{operator.inspect}"
85
102
  end
86
103
  end
87
- # rubocop:enable Metrics/CyclomaticComplexity
88
104
 
89
105
  def match_all?(json, response_body)
90
106
  return true if json.nil?
@@ -4,6 +4,7 @@ module MyApiClient
4
4
  # The ancestor class for all API request error
5
5
  class Error < StandardError
6
6
  attr_reader :params
7
+
7
8
  delegate :metadata, to: :params
8
9
  alias to_bugsnag metadata
9
10
 
@@ -25,57 +26,4 @@ module MyApiClient
25
26
  { error: super, params: params }.inspect
26
27
  end
27
28
  end
28
-
29
- NETWORK_ERRORS = [
30
- Faraday::TimeoutError,
31
- Faraday::ConnectionFailed,
32
- Faraday::SSLError,
33
- OpenSSL::SSL::SSLError,
34
- Net::OpenTimeout,
35
- Net::ReadTimeout,
36
- SocketError,
37
- ].freeze
38
-
39
- # Raises it when occurred to some network error
40
- class NetworkError < Error
41
- attr_reader :original_error
42
-
43
- # Initialize the error class
44
- #
45
- # @param params [MyApiClient::Params::Params]
46
- # The request and response parameters
47
- # @param original_error [StandardError]
48
- # Some network error
49
- def initialize(params, original_error)
50
- @original_error = original_error
51
- super params, original_error.message
52
- end
53
-
54
- # Returns contents as string for to be readable for human
55
- #
56
- # @return [String] Contents as string
57
- def inspect
58
- { error: original_error, params: params }.inspect
59
- end
60
-
61
- # Generate metadata for bugsnag.
62
- #
63
- # @return [Hash] Metadata for bugsnag
64
- def metadata
65
- super.merge(original_error: original_error.inspect)
66
- end
67
- end
68
-
69
- # NOTE: The built-in error classes are following. Although they are prepared
70
- # to save the trouble of defining, but you can create any error classes
71
- # which inherit the ancestor error class.
72
-
73
- # For 4xx client error
74
- class ClientError < Error; end
75
-
76
- # For 5xx server error
77
- class ServerError < Error; end
78
-
79
- # For API request limit error
80
- class ApiLimitError < Error; end
81
29
  end