my_api_client 0.14.0.pre → 0.17.0
Sign up to get free protection for your applications and to get access to all the features.
- 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?
|