my_api_client 0.14.0.pre → 0.17.0
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/.circleci/config.yml +179 -38
- data/.dependabot/config.yml +19 -1
- data/.envrc.skeleton +1 -0
- data/.rubocop.yml +9 -1
- data/.rubocop_challenge.yml +5 -0
- data/.rubocop_todo.yml +29 -1
- data/CHANGELOG.md +177 -1
- data/Gemfile.lock +47 -45
- data/README.jp.md +156 -21
- data/bin/console +4 -0
- data/example/api_clients/application_api_client.rb +13 -0
- data/example/api_clients/my_error_api_client.rb +34 -0
- data/example/api_clients/my_errors.rb +27 -0
- data/example/api_clients/my_pagination_api_client.rb +18 -0
- data/example/api_clients/my_rest_api_client.rb +48 -0
- data/example/api_clients/my_status_api_client.rb +22 -0
- data/lib/generators/rails/templates/application_api_client.rb.erb +0 -11
- data/lib/generators/rspec/templates/api_client_spec.rb.erb +22 -15
- data/lib/my_api_client.rb +7 -0
- data/lib/my_api_client/base.rb +4 -2
- data/lib/my_api_client/default_error_handlers.rb +64 -0
- data/lib/my_api_client/error_handling.rb +6 -6
- data/lib/my_api_client/error_handling/generator.rb +23 -7
- data/lib/my_api_client/errors.rb +1 -53
- data/lib/my_api_client/errors/api_limit_error.rb +6 -0
- data/lib/my_api_client/errors/client_error.rb +93 -0
- data/lib/my_api_client/errors/network_error.rb +43 -0
- data/lib/my_api_client/errors/server_error.rb +42 -0
- data/lib/my_api_client/request.rb +29 -34
- data/lib/my_api_client/request/basic.rb +32 -0
- data/lib/my_api_client/request/executor.rb +1 -1
- data/lib/my_api_client/request/pagination.rb +39 -0
- data/lib/my_api_client/rspec/matchers/request_to.rb +3 -4
- data/lib/my_api_client/version.rb +1 -1
- data/my_api/.envrc.skeleton +3 -0
- data/my_api/.gitignore +14 -0
- data/my_api/.jetskeep +1 -0
- data/my_api/.rspec +3 -0
- data/my_api/.ruby-version +1 -0
- data/my_api/Gemfile +23 -0
- data/my_api/Gemfile.lock +243 -0
- data/my_api/Procfile +7 -0
- data/my_api/README.md +54 -0
- data/my_api/Rakefile +4 -0
- data/my_api/app/controllers/application_controller.rb +5 -0
- data/my_api/app/controllers/error_controller.rb +21 -0
- data/my_api/app/controllers/pagination_controller.rb +58 -0
- data/my_api/app/controllers/rest_controller.rb +60 -0
- data/my_api/app/controllers/status_controller.rb +11 -0
- data/my_api/app/helpers/application_helper.rb +5 -0
- data/my_api/app/jobs/application_job.rb +7 -0
- data/my_api/app/models/application_item.rb +5 -0
- data/my_api/config.ru +7 -0
- data/my_api/config/application.rb +73 -0
- data/my_api/config/dynamodb.yml +22 -0
- data/my_api/config/environments/development.rb +9 -0
- data/my_api/config/environments/production.rb +11 -0
- data/my_api/config/environments/test.rb +9 -0
- data/my_api/config/routes.rb +17 -0
- data/my_api/db/.gitkeep +0 -0
- data/my_api/public/404.html +67 -0
- data/my_api/public/422.html +67 -0
- data/my_api/public/500.html +66 -0
- data/my_api/public/favicon.ico +0 -0
- data/my_api/public/index.html +91 -0
- data/my_api/spec/controllers/error_controller_spec.rb +43 -0
- data/my_api/spec/controllers/pagination_controller_spec.rb +73 -0
- data/my_api/spec/controllers/rest_controller_spec.rb +99 -0
- data/my_api/spec/controllers/status_controller_spec.rb +47 -0
- data/my_api/spec/fixtures/payloads/posts-index.json +51 -0
- data/my_api/spec/fixtures/payloads/posts-show.json +53 -0
- data/my_api/spec/spec_helper.rb +31 -0
- data/rails_app/rails_5.2/.rspec +3 -0
- data/rails_app/rails_5.2/Gemfile +18 -0
- data/rails_app/rails_5.2/Gemfile.lock +171 -0
- data/rails_app/rails_5.2/README.md +24 -0
- data/rails_app/rails_5.2/Rakefile +8 -0
- data/rails_app/rails_5.2/app/controllers/application_controller.rb +4 -0
- data/rails_app/rails_5.2/app/jobs/application_job.rb +4 -0
- data/rails_app/rails_5.2/bin/bundle +5 -0
- data/rails_app/rails_5.2/bin/rails +6 -0
- data/rails_app/rails_5.2/bin/rake +6 -0
- data/rails_app/rails_5.2/bin/setup +27 -0
- data/rails_app/rails_5.2/bin/update +27 -0
- data/rails_app/rails_5.2/config.ru +7 -0
- data/rails_app/rails_5.2/config/application.rb +37 -0
- data/rails_app/rails_5.2/config/boot.rb +6 -0
- data/rails_app/rails_5.2/config/credentials.yml.enc +1 -0
- data/rails_app/rails_5.2/config/environment.rb +7 -0
- data/rails_app/rails_5.2/config/environments/development.rb +41 -0
- data/rails_app/rails_5.2/config/environments/production.rb +70 -0
- data/rails_app/rails_5.2/config/environments/test.rb +38 -0
- data/rails_app/rails_5.2/config/initializers/application_controller_renderer.rb +9 -0
- data/rails_app/rails_5.2/config/initializers/backtrace_silencers.rb +8 -0
- data/rails_app/rails_5.2/config/initializers/cors.rb +17 -0
- data/rails_app/rails_5.2/config/initializers/filter_parameter_logging.rb +6 -0
- data/rails_app/rails_5.2/config/initializers/inflections.rb +17 -0
- data/rails_app/rails_5.2/config/initializers/mime_types.rb +5 -0
- data/rails_app/rails_5.2/config/initializers/wrap_parameters.rb +11 -0
- data/rails_app/rails_5.2/config/locales/en.yml +33 -0
- data/rails_app/rails_5.2/config/routes.rb +5 -0
- data/rails_app/rails_5.2/config/spring.rb +8 -0
- data/rails_app/rails_5.2/public/robots.txt +1 -0
- data/rails_app/rails_5.2/spec/rails_helper.rb +14 -0
- data/rails_app/rails_5.2/spec/spec_helper.rb +13 -0
- data/rails_app/rails_6.0/.rspec +3 -0
- data/rails_app/rails_6.0/Gemfile +17 -0
- data/rails_app/rails_6.0/Gemfile.lock +186 -0
- data/rails_app/rails_6.0/README.md +24 -0
- data/rails_app/rails_6.0/Rakefile +8 -0
- data/rails_app/rails_6.0/app/controllers/application_controller.rb +4 -0
- data/rails_app/rails_6.0/app/jobs/application_job.rb +9 -0
- data/rails_app/rails_6.0/bin/rails +6 -0
- data/rails_app/rails_6.0/bin/rake +6 -0
- data/rails_app/rails_6.0/bin/setup +27 -0
- data/rails_app/rails_6.0/config.ru +7 -0
- data/rails_app/rails_6.0/config/application.rb +39 -0
- data/rails_app/rails_6.0/config/boot.rb +6 -0
- data/rails_app/rails_6.0/config/credentials.yml.enc +1 -0
- data/rails_app/rails_6.0/config/environment.rb +7 -0
- data/rails_app/rails_6.0/config/environments/development.rb +39 -0
- data/rails_app/rails_6.0/config/environments/production.rb +90 -0
- data/rails_app/rails_6.0/config/environments/test.rb +41 -0
- data/rails_app/rails_6.0/config/initializers/application_controller_renderer.rb +9 -0
- data/rails_app/rails_6.0/config/initializers/backtrace_silencers.rb +8 -0
- data/rails_app/rails_6.0/config/initializers/cors.rb +17 -0
- data/rails_app/rails_6.0/config/initializers/filter_parameter_logging.rb +6 -0
- data/rails_app/rails_6.0/config/initializers/inflections.rb +17 -0
- data/rails_app/rails_6.0/config/initializers/mime_types.rb +5 -0
- data/rails_app/rails_6.0/config/initializers/wrap_parameters.rb +11 -0
- data/rails_app/rails_6.0/config/locales/en.yml +33 -0
- data/rails_app/rails_6.0/config/routes.rb +5 -0
- data/rails_app/rails_6.0/config/spring.rb +8 -0
- data/rails_app/rails_6.0/public/robots.txt +1 -0
- data/rails_app/rails_6.0/spec/rails_helper.rb +14 -0
- data/rails_app/rails_6.0/spec/spec_helper.rb +13 -0
- metadata +120 -5
- data/renovate.json +0 -21
data/bin/console
CHANGED
@@ -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.
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'my_errors'
|
4
|
+
|
5
|
+
# An usage example of the `my_api_client`.
|
6
|
+
class ApplicationApiClient < MyApiClient::Base
|
7
|
+
endpoint ENV['MY_API_ENDPOINT']
|
8
|
+
|
9
|
+
self.logger = ::Logger.new(nil)
|
10
|
+
|
11
|
+
http_open_timeout 5.seconds
|
12
|
+
http_read_timeout 5.seconds
|
13
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'application_api_client'
|
4
|
+
|
5
|
+
# An usage example of the `my_api_client`.
|
6
|
+
# See also: my_api/app/controllers/status_controller.rb
|
7
|
+
class MyErrorApiClient < ApplicationApiClient
|
8
|
+
error_handling json: { '$.error.message': /You requested error code/ },
|
9
|
+
raise: MyErrors::ErrorCodeOther
|
10
|
+
|
11
|
+
error_handling json: { '$.error.code': :zero? },
|
12
|
+
raise: MyErrors::ErrorCode00
|
13
|
+
|
14
|
+
error_handling json: { '$.error.code': 10 },
|
15
|
+
raise: MyErrors::ErrorCode10
|
16
|
+
|
17
|
+
error_handling json: { '$.error.code': 20..29 },
|
18
|
+
raise: MyErrors::ErrorCode2x
|
19
|
+
|
20
|
+
error_handling json: { '$.error.code': 30 },
|
21
|
+
status_code: 400,
|
22
|
+
raise: MyErrors::ErrorCode30
|
23
|
+
|
24
|
+
# GET error/:code
|
25
|
+
def get_error(code:)
|
26
|
+
get "error/#{code}", headers: headers
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def headers
|
32
|
+
{ 'Content-Type': 'application/json;charset=UTF-8' }
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MyErrors
|
4
|
+
# 400 Bad Request
|
5
|
+
class BadRequest < MyApiClient::ClientError; end
|
6
|
+
|
7
|
+
# 401 Unauthorized
|
8
|
+
class Unauthorized < MyApiClient::ClientError; end
|
9
|
+
|
10
|
+
# 403 Forbidden
|
11
|
+
class Forbidden < MyApiClient::ClientError; end
|
12
|
+
|
13
|
+
# Error code: 0
|
14
|
+
class ErrorCode00 < MyApiClient::ClientError; end
|
15
|
+
|
16
|
+
# Error code: 10
|
17
|
+
class ErrorCode10 < MyApiClient::ClientError; end
|
18
|
+
|
19
|
+
# Error code: 20 to 29
|
20
|
+
class ErrorCode2x < MyApiClient::ClientError; end
|
21
|
+
|
22
|
+
# Error code: 30
|
23
|
+
class ErrorCode30 < MyApiClient::ClientError; end
|
24
|
+
|
25
|
+
# Error code: other
|
26
|
+
class ErrorCodeOther < MyApiClient::ClientError; end
|
27
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'application_api_client'
|
4
|
+
|
5
|
+
# An usage example of the `my_api_client`.
|
6
|
+
# See also: my_api/app/controllers/pagination_controller.rb
|
7
|
+
class MyPaginationApiClient < ApplicationApiClient
|
8
|
+
# GET pagination?page=1
|
9
|
+
def pagination
|
10
|
+
pget 'pagination', paging: '$.links.next', headers: headers, query: { page: 1 }
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def headers
|
16
|
+
{ 'Content-Type': 'application/json;charset=UTF-8' }
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'application_api_client'
|
4
|
+
|
5
|
+
# An usage example of the `my_api_client`.
|
6
|
+
# See also: my_api/app/controllers/rest_controller.rb
|
7
|
+
class MyRestApiClient < ApplicationApiClient
|
8
|
+
# GET rest
|
9
|
+
def get_posts(order: :asc)
|
10
|
+
order = :desc unless order == :asc
|
11
|
+
query = { order: order }
|
12
|
+
get 'rest', query: query, headers: headers
|
13
|
+
end
|
14
|
+
|
15
|
+
# GET rest/:id
|
16
|
+
def get_post(id:)
|
17
|
+
get "rest/#{id}", headers: headers
|
18
|
+
end
|
19
|
+
|
20
|
+
# POST rest
|
21
|
+
def post_post(title:)
|
22
|
+
body = { title: title }
|
23
|
+
post 'rest', body: body, headers: headers
|
24
|
+
end
|
25
|
+
|
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:)
|
34
|
+
body = { title: title }
|
35
|
+
patch "rest/#{id}", body: body, headers: headers
|
36
|
+
end
|
37
|
+
|
38
|
+
# DELETE rest/:id
|
39
|
+
def delete_post(id:)
|
40
|
+
delete "rest/#{id}", headers: headers
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def headers
|
46
|
+
{ 'Content-Type': 'application/json;charset=UTF-8' }
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'application_api_client'
|
4
|
+
|
5
|
+
# An usage example of the `my_api_client`.
|
6
|
+
# See also: my_api/app/controllers/status_controller.rb
|
7
|
+
class MyStatusApiClient < ApplicationApiClient
|
8
|
+
error_handling status_code: 400, raise: MyErrors::BadRequest
|
9
|
+
error_handling status_code: 401, raise: MyErrors::Unauthorized
|
10
|
+
error_handling status_code: 403, raise: MyErrors::Forbidden
|
11
|
+
|
12
|
+
# GET status/:status
|
13
|
+
def get_status(status:)
|
14
|
+
get "status/#{status}", headers: headers
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def headers
|
20
|
+
{ 'Content-Type': 'application/json;charset=UTF-8' }
|
21
|
+
end
|
22
|
+
end
|
@@ -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
|
@@ -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
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
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
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
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,6 +40,8 @@ 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
47
|
.to request_to(:<%= http_method %>, 'https://example.com/<%= pathname %>')
|
@@ -37,13 +51,6 @@ RSpec.describe <%= "#{class_name}ApiClient" %>, <%= type_metatag(:api_client) %>
|
|
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
|
data/lib/my_api_client.rb
CHANGED
@@ -16,7 +16,14 @@ require 'my_api_client/error_handling'
|
|
16
16
|
require 'my_api_client/exceptions'
|
17
17
|
require 'my_api_client/request/logger'
|
18
18
|
require 'my_api_client/request/executor'
|
19
|
+
require 'my_api_client/request/basic'
|
20
|
+
require 'my_api_client/request/pagination'
|
19
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'
|
20
27
|
require 'my_api_client/params/params'
|
21
28
|
require 'my_api_client/params/request'
|
22
29
|
require 'my_api_client/request'
|
data/lib/my_api_client/base.rb
CHANGED
@@ -9,15 +9,17 @@ module MyApiClient
|
|
9
9
|
include MyApiClient::Request
|
10
10
|
|
11
11
|
if ActiveSupport::VERSION::STRING >= '5.2.0'
|
12
|
-
class_attribute :logger, instance_writer: false, default: ::Logger.new(
|
12
|
+
class_attribute :logger, instance_writer: false, default: ::Logger.new($stdout)
|
13
13
|
class_attribute :error_handlers, instance_writer: false, default: []
|
14
14
|
else
|
15
15
|
class_attribute :logger
|
16
16
|
class_attribute :error_handlers
|
17
|
-
self.logger = ::Logger.new(
|
17
|
+
self.logger = ::Logger.new($stdout)
|
18
18
|
self.error_handlers = []
|
19
19
|
end
|
20
20
|
|
21
|
+
include MyApiClient::DefaultErrorHandlers
|
22
|
+
|
21
23
|
# NOTE: This class **MUST NOT** implement #initialize method. Because it
|
22
24
|
# will become constraint that need call #super in the #initialize at
|
23
25
|
# definition of the child classes.
|
@@ -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
|
@@ -29,10 +28,11 @@ module MyApiClient
|
|
29
28
|
# @option status_code [String, Range, Integer, Regexp]
|
30
29
|
# Verifies response HTTP status code and raises error if matched
|
31
30
|
# @option json [Hash, Symbol]
|
32
|
-
#
|
33
|
-
#
|
31
|
+
# Specify the validation target value path included in the response body
|
32
|
+
# as JsonPath expression.
|
33
|
+
# If specified `:forbid_nil`, it forbid `nil` at the response body.
|
34
34
|
# @option with [Symbol]
|
35
|
-
# Calls specified method when error detected
|
35
|
+
# Calls specified method before raising exception when error detected.
|
36
36
|
# @option raise [MyApiClient::Error]
|
37
37
|
# Raises specified error when an invalid response detected.
|
38
38
|
# Should be inherited `MyApiClient::Error` class.
|
@@ -41,7 +41,7 @@ module MyApiClient
|
|
41
41
|
# If the error detected, retries the API request. Requires `raise` option.
|
42
42
|
# You can set `true` or `retry_on` options (`wait` and `attempts`).
|
43
43
|
# @yield [MyApiClient::Params::Params, MyApiClient::Request::Logger]
|
44
|
-
# Executes the block when error detected.
|
44
|
+
# Executes the block before raising exception when error detected.
|
45
45
|
# Forbid to be used with the` retry` option.
|
46
46
|
def error_handling(**options, &block)
|
47
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
|
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
|
-
|
46
|
+
block_caller
|
47
47
|
elsif _with
|
48
|
-
|
48
|
+
method_caller
|
49
49
|
else
|
50
|
-
|
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?
|