my_api_client 0.22.0 → 0.24.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 +26 -26
- data/.rubocop.yml +14 -10
- data/.rubocop_todo.yml +2 -2
- data/CHANGELOG.md +220 -157
- data/Gemfile +0 -2
- data/Gemfile.lock +51 -68
- data/README.jp.md +38 -22
- data/README.md +25 -11
- data/example/api_clients/application_api_client.rb +1 -1
- data/example/api_clients/my_errors.rb +9 -0
- data/example/api_clients/my_header_api_client.rb +38 -0
- data/lib/my_api_client/error_handling/generator.rb +16 -3
- data/lib/my_api_client/errors/network_error.rb +3 -3
- data/lib/my_api_client/errors.rb +2 -2
- data/lib/my_api_client/integrations/bugsnag.rb +2 -2
- data/lib/my_api_client/version.rb +1 -1
- data/my_api/Gemfile +2 -2
- data/my_api/Gemfile.lock +94 -94
- data/my_api/app/controllers/header_controller.rb +12 -0
- data/my_api/app/controllers/pagination_controller.rb +1 -1
- data/my_api/config/routes.rb +1 -0
- data/my_api/spec/controllers/error_controller_spec.rb +1 -1
- data/my_api/spec/controllers/header_controller_spec.rb +33 -0
- data/my_api/spec/controllers/pagination_controller_spec.rb +1 -1
- data/my_api/spec/controllers/rest_controller_spec.rb +1 -1
- data/my_api/spec/controllers/status_controller_spec.rb +1 -1
- data/my_api_client.gemspec +1 -1
- data/rails_app/rails_5.2/Gemfile.lock +8 -8
- data/rails_app/rails_6.0/Gemfile +1 -0
- data/rails_app/rails_6.0/Gemfile.lock +84 -98
- data/rails_app/rails_6.1/Gemfile.lock +89 -99
- data/rails_app/rails_7.0/Gemfile.lock +132 -69
- metadata +7 -4
data/Gemfile
CHANGED
@@ -4,8 +4,6 @@ source 'https://rubygems.org'
|
|
4
4
|
|
5
5
|
git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
|
6
6
|
|
7
|
-
gem 'activesupport', '~> 6.1' # TODO: Remove this line at the end of Ruby 2.6 support
|
8
|
-
|
9
7
|
group :integrations, optional: true do
|
10
8
|
gem 'bugsnag', '>= 6.11.0'
|
11
9
|
end
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
my_api_client (0.
|
4
|
+
my_api_client (0.24.0)
|
5
5
|
activesupport (>= 5.2.0)
|
6
6
|
faraday (>= 0.17.1)
|
7
7
|
jsonpath
|
@@ -10,125 +10,108 @@ PATH
|
|
10
10
|
GEM
|
11
11
|
remote: https://rubygems.org/
|
12
12
|
specs:
|
13
|
-
activesupport (
|
13
|
+
activesupport (7.0.4)
|
14
14
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
15
15
|
i18n (>= 1.6, < 2)
|
16
16
|
minitest (>= 5.1)
|
17
17
|
tzinfo (~> 2.0)
|
18
|
-
|
19
|
-
|
20
|
-
public_suffix (>= 2.0.2, < 5.0)
|
18
|
+
addressable (2.8.1)
|
19
|
+
public_suffix (>= 2.0.2, < 6.0)
|
21
20
|
ast (2.4.2)
|
22
|
-
bugsnag (6.24.
|
21
|
+
bugsnag (6.24.2)
|
23
22
|
concurrent-ruby (~> 1.0)
|
24
23
|
byebug (11.1.3)
|
25
24
|
coderay (1.1.3)
|
26
|
-
concurrent-ruby (1.1.
|
25
|
+
concurrent-ruby (1.1.10)
|
27
26
|
crack (0.4.5)
|
28
27
|
rexml
|
29
28
|
diff-lcs (1.5.0)
|
30
29
|
docile (1.4.0)
|
31
|
-
faraday (
|
32
|
-
faraday-
|
33
|
-
faraday-em_synchrony (~> 1.0)
|
34
|
-
faraday-excon (~> 1.1)
|
35
|
-
faraday-httpclient (~> 1.0.1)
|
36
|
-
faraday-net_http (~> 1.0)
|
37
|
-
faraday-net_http_persistent (~> 1.1)
|
38
|
-
faraday-patron (~> 1.0)
|
39
|
-
faraday-rack (~> 1.0)
|
40
|
-
multipart-post (>= 1.2, < 3)
|
30
|
+
faraday (2.6.0)
|
31
|
+
faraday-net_http (>= 2.0, < 3.1)
|
41
32
|
ruby2_keywords (>= 0.0.4)
|
42
|
-
faraday-
|
43
|
-
faraday-em_synchrony (1.0.0)
|
44
|
-
faraday-excon (1.1.0)
|
45
|
-
faraday-httpclient (1.0.1)
|
46
|
-
faraday-net_http (1.0.1)
|
47
|
-
faraday-net_http_persistent (1.2.0)
|
48
|
-
faraday-patron (1.0.0)
|
49
|
-
faraday-rack (1.0.0)
|
33
|
+
faraday-net_http (3.0.1)
|
50
34
|
hashdiff (1.0.1)
|
51
|
-
i18n (1.
|
35
|
+
i18n (1.12.0)
|
52
36
|
concurrent-ruby (~> 1.0)
|
53
|
-
|
37
|
+
json (2.6.2)
|
38
|
+
jsonpath (1.1.2)
|
54
39
|
multi_json
|
55
40
|
method_source (1.0.0)
|
56
|
-
minitest (5.
|
41
|
+
minitest (5.16.3)
|
57
42
|
multi_json (1.15.0)
|
58
|
-
|
59
|
-
|
60
|
-
parser (3.0.3.2)
|
43
|
+
parallel (1.22.1)
|
44
|
+
parser (3.1.2.1)
|
61
45
|
ast (~> 2.4.1)
|
62
|
-
pry (0.
|
46
|
+
pry (0.14.1)
|
63
47
|
coderay (~> 1.1)
|
64
48
|
method_source (~> 1.0)
|
65
|
-
pry-byebug (3.
|
49
|
+
pry-byebug (3.10.1)
|
66
50
|
byebug (~> 11.0)
|
67
|
-
pry (
|
68
|
-
public_suffix (
|
69
|
-
rainbow (3.
|
51
|
+
pry (>= 0.13, < 0.15)
|
52
|
+
public_suffix (5.0.0)
|
53
|
+
rainbow (3.1.1)
|
70
54
|
rake (13.0.6)
|
71
|
-
regexp_parser (2.
|
55
|
+
regexp_parser (2.6.0)
|
72
56
|
rexml (3.2.5)
|
73
|
-
rspec (3.
|
74
|
-
rspec-core (~> 3.
|
75
|
-
rspec-expectations (~> 3.
|
76
|
-
rspec-mocks (~> 3.
|
77
|
-
rspec-core (3.
|
78
|
-
rspec-support (~> 3.
|
79
|
-
rspec-expectations (3.
|
57
|
+
rspec (3.12.0)
|
58
|
+
rspec-core (~> 3.12.0)
|
59
|
+
rspec-expectations (~> 3.12.0)
|
60
|
+
rspec-mocks (~> 3.12.0)
|
61
|
+
rspec-core (3.12.0)
|
62
|
+
rspec-support (~> 3.12.0)
|
63
|
+
rspec-expectations (3.12.0)
|
80
64
|
diff-lcs (>= 1.2.0, < 2.0)
|
81
|
-
rspec-support (~> 3.
|
82
|
-
rspec-mocks (3.
|
65
|
+
rspec-support (~> 3.12.0)
|
66
|
+
rspec-mocks (3.12.0)
|
83
67
|
diff-lcs (>= 1.2.0, < 2.0)
|
84
|
-
rspec-support (~> 3.
|
85
|
-
rspec-support (3.
|
86
|
-
rspec_junit_formatter (0.
|
68
|
+
rspec-support (~> 3.12.0)
|
69
|
+
rspec-support (3.12.0)
|
70
|
+
rspec_junit_formatter (0.6.0)
|
87
71
|
rspec-core (>= 2, < 4, != 2.12.0)
|
88
|
-
rubocop (1.
|
72
|
+
rubocop (1.38.0)
|
73
|
+
json (~> 2.3)
|
89
74
|
parallel (~> 1.10)
|
90
|
-
parser (>= 3.
|
75
|
+
parser (>= 3.1.2.1)
|
91
76
|
rainbow (>= 2.2.2, < 4.0)
|
92
77
|
regexp_parser (>= 1.8, < 3.0)
|
93
|
-
rexml
|
94
|
-
rubocop-ast (>= 1.
|
78
|
+
rexml (>= 3.2.5, < 4.0)
|
79
|
+
rubocop-ast (>= 1.23.0, < 2.0)
|
95
80
|
ruby-progressbar (~> 1.7)
|
96
81
|
unicode-display_width (>= 1.4.0, < 3.0)
|
97
|
-
rubocop-ast (1.
|
98
|
-
parser (>= 3.
|
99
|
-
rubocop-performance (1.
|
82
|
+
rubocop-ast (1.23.0)
|
83
|
+
parser (>= 3.1.1.0)
|
84
|
+
rubocop-performance (1.15.0)
|
100
85
|
rubocop (>= 1.7.0, < 2.0)
|
101
86
|
rubocop-ast (>= 0.4.0)
|
102
|
-
rubocop-rspec (2.
|
103
|
-
rubocop (~> 1.
|
87
|
+
rubocop-rspec (2.15.0)
|
88
|
+
rubocop (~> 1.33)
|
104
89
|
ruby-progressbar (1.11.0)
|
105
90
|
ruby2_keywords (0.0.5)
|
106
|
-
sawyer (0.
|
91
|
+
sawyer (0.9.2)
|
107
92
|
addressable (>= 2.3.5)
|
108
|
-
faraday (
|
93
|
+
faraday (>= 0.17.3, < 3)
|
109
94
|
simplecov (0.21.2)
|
110
95
|
docile (~> 1.1)
|
111
96
|
simplecov-html (~> 0.11)
|
112
97
|
simplecov_json_formatter (~> 0.1)
|
113
98
|
simplecov-html (0.12.3)
|
114
|
-
simplecov_json_formatter (0.1.
|
115
|
-
tzinfo (2.0.
|
99
|
+
simplecov_json_formatter (0.1.4)
|
100
|
+
tzinfo (2.0.5)
|
116
101
|
concurrent-ruby (~> 1.0)
|
117
|
-
unicode-display_width (2.
|
118
|
-
webmock (3.
|
102
|
+
unicode-display_width (2.3.0)
|
103
|
+
webmock (3.18.1)
|
119
104
|
addressable (>= 2.8.0)
|
120
105
|
crack (>= 0.3.2)
|
121
106
|
hashdiff (>= 0.4.0, < 2.0.0)
|
122
107
|
webrick (1.7.0)
|
123
|
-
yard (0.9.
|
108
|
+
yard (0.9.28)
|
124
109
|
webrick (~> 1.7.0)
|
125
|
-
zeitwerk (2.5.1)
|
126
110
|
|
127
111
|
PLATFORMS
|
128
112
|
ruby
|
129
113
|
|
130
114
|
DEPENDENCIES
|
131
|
-
activesupport (~> 6.1)
|
132
115
|
bugsnag (>= 6.11.0)
|
133
116
|
bundler (>= 2.0)
|
134
117
|
my_api_client!
|
@@ -144,4 +127,4 @@ DEPENDENCIES
|
|
144
127
|
yard
|
145
128
|
|
146
129
|
BUNDLED WITH
|
147
|
-
2.
|
130
|
+
2.3.11
|
data/README.jp.md
CHANGED
@@ -12,8 +12,8 @@ MyApiClient は API リクエストクラスを作成するための汎用的な
|
|
12
12
|
|
13
13
|
## Supported Versions
|
14
14
|
|
15
|
-
|
16
|
-
|
15
|
+
- Ruby 2.7, 3.0, 3.1
|
16
|
+
- Rails 5.2, 6.0, 6.1, 7.0
|
17
17
|
|
18
18
|
## Installation
|
19
19
|
|
@@ -116,7 +116,7 @@ end
|
|
116
116
|
{
|
117
117
|
"links": {
|
118
118
|
"next": "https://example.com/pagination?page=3",
|
119
|
-
"previous": "https://example.com/pagination?page=1"
|
119
|
+
"previous": "https://example.com/pagination?page=1"
|
120
120
|
},
|
121
121
|
"page": 2
|
122
122
|
}
|
@@ -200,7 +200,7 @@ error_handling status_code: 500..599, raise: MyApiClient::ServerError do |_param
|
|
200
200
|
end
|
201
201
|
```
|
202
202
|
|
203
|
-
上記の例であれば、ステータスコードが `500..599` の場合に `MyApiClient::ServerError`
|
203
|
+
上記の例であれば、ステータスコードが `500..599` の場合に `MyApiClient::ServerError` を発生させる前に `block` の内容が実行れます。引数の `params` にはリクエスト情報とレスポンス情報が含まれています。`logger` はログ出力用インスタンスですが、このインスタンスを使ってログ出力すると、以下のようにリクエスト情報がログ出力に含まれるようになり、デバッグの際に便利です。
|
204
204
|
|
205
205
|
```text
|
206
206
|
API request `GET https://example.com/path/to/resouce`: "Server error occurred."
|
@@ -214,13 +214,30 @@ error_handling json: { '$.errors.code': 10..19 }, with: :my_error_handling
|
|
214
214
|
|
215
215
|
```json
|
216
216
|
{
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
217
|
+
"erros": {
|
218
|
+
"code": 10,
|
219
|
+
"message": "Some error has occurred."
|
220
|
+
}
|
221
221
|
}
|
222
222
|
```
|
223
223
|
|
224
|
+
`headers` には `Hash` の Key に レスポンスのヘッダーキーを指定して、 Value とマッチするかどうかでエラーハンドリングできます。Value には `String` `Regexp` が指定可能です。
|
225
|
+
|
226
|
+
|
227
|
+
```ruby
|
228
|
+
error_handling headers: { 'www-authenticate': /invalid token/ }, with: :my_error_handling
|
229
|
+
```
|
230
|
+
|
231
|
+
上記の場合であれば、以下のような レスポンスヘッダー にマッチします。
|
232
|
+
|
233
|
+
```text
|
234
|
+
cache-control: no-cache, no-store, max-age=0, must-revalidate
|
235
|
+
content-type: application/json
|
236
|
+
www-authenticate: Bearer error="invalid_token", error_description="invalid token"
|
237
|
+
content-length: 104
|
238
|
+
```
|
239
|
+
|
240
|
+
|
224
241
|
`with` にはインスタンスメソッド名を指定することで、エラーを検出した際、例外を発生させる前に任意のメソッドを実行させることができます。メソッドに渡される引数は `block` 定義の場合と同じく `params` と `logger` です。なお、 `block` と `with` は同時には利用できません。
|
225
242
|
|
226
243
|
```ruby
|
@@ -253,10 +270,10 @@ error_handling json: { '$.errors.code': :negative? }
|
|
253
270
|
|
254
271
|
```json
|
255
272
|
{
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
273
|
+
"erros": {
|
274
|
+
"code": -1,
|
275
|
+
"message": "Some error has occurred."
|
276
|
+
}
|
260
277
|
}
|
261
278
|
```
|
262
279
|
|
@@ -344,8 +361,8 @@ error_handling json: { '$.errors.code': 20 },
|
|
344
361
|
|
345
362
|
`retry` オプションを使用する際は以下の点に注意が必要です。
|
346
363
|
|
347
|
-
|
348
|
-
|
364
|
+
- `error_handling` に `raise` オプションの指定が必須となります。
|
365
|
+
- Block を使った `error_handling` の定義は禁止されます。
|
349
366
|
|
350
367
|
#### MyApiClient::NetworkError
|
351
368
|
|
@@ -654,7 +671,7 @@ end
|
|
654
671
|
|
655
672
|
#### `pageable` option
|
656
673
|
|
657
|
-
`#pageable_get`
|
674
|
+
`#pageable_get` (`#pget`) を使った実装用に `pageable` というオプションが利用できます。
|
658
675
|
`pageable` に設定する値は `Enumerable` である必要があります。
|
659
676
|
|
660
677
|
```ruby
|
@@ -692,7 +709,6 @@ stub_api_client_all(
|
|
692
709
|
|
693
710
|
また、 `Enumerator` を使えば無限に続くページネーションを定義することもできます。
|
694
711
|
|
695
|
-
|
696
712
|
```ruby
|
697
713
|
stub_api_client_all(
|
698
714
|
MyPaginationApiClient,
|
@@ -742,10 +758,10 @@ $ gem_comet release {VERSION}
|
|
742
758
|
|
743
759
|
実行すると、 https://github.com/ryz310/my_api_client/pulls に以下のような PR が作成されます。
|
744
760
|
|
745
|
-
|
746
|
-
|
761
|
+
- [Update v0\.16\.1](https://github.com/ryz310/my_api_client/pull/297)
|
762
|
+
- [Release v0\.16\.1](https://github.com/ryz310/my_api_client/pull/298)
|
747
763
|
|
748
|
-
まず、 `Update v{VERSION}`
|
764
|
+
まず、 `Update v{VERSION}` という PR から merge に取り掛かります。
|
749
765
|
|
750
766
|
PR のコメントにも TODO が記載されていますが、まず、バージョン番号が正しく採番されているかを確認します。
|
751
767
|
|
@@ -755,12 +771,12 @@ See: [314a4c0](https://github.com/ryz310/my_api_client/pull/297/commits/314a4c06
|
|
755
771
|
|
756
772
|
See: [33a2d17](https://github.com/ryz310/my_api_client/pull/297/commits/33a2d1703c773813c837e74ee3181906b2f2e502)
|
757
773
|
|
758
|
-
これらが整ったら、 `Update v{VERSION}`
|
774
|
+
これらが整ったら、 `Update v{VERSION}` を merge します。
|
759
775
|
|
760
|
-
これでリリース準備が整ったので、`Release v{VERSION}`
|
776
|
+
これでリリース準備が整ったので、`Release v{VERSION}` の merge に取り掛かります。
|
761
777
|
|
762
778
|
この PR にこれからリリースする gem に対する変更が全て載っています。
|
763
|
-
変更内容の最終確認をして、 CI も通ったことを確認したら `Release v{VERSION}`
|
779
|
+
変更内容の最終確認をして、 CI も通ったことを確認したら `Release v{VERSION}` を merge します。
|
764
780
|
|
765
781
|
あとは Circle CI 側で gem のリリースが自動実行されるので、暫く待ちましょう。
|
766
782
|
|
data/README.md
CHANGED
@@ -12,8 +12,8 @@ It is supposed to be used in Ruby on Rails, but it is made to work in other envi
|
|
12
12
|
|
13
13
|
## Supported Versions
|
14
14
|
|
15
|
-
|
16
|
-
|
15
|
+
- Ruby 2.7, 3.0, 3.1
|
16
|
+
- Rails 5.2, 6.0, 6.1, 7.0
|
17
17
|
|
18
18
|
## Installation
|
19
19
|
|
@@ -83,7 +83,7 @@ The `endpoint` defines the intersection of the request URL. Each method describe
|
|
83
83
|
|
84
84
|
Next, define `#initialize`. Suppose you want to set an Access Token, API Key, etc. as in the example above. You can omit the definition if you don't need it.
|
85
85
|
|
86
|
-
Then define `#
|
86
|
+
Then define `#get_users` and `#post_user`. It's a good idea to give the method name the title of the API. I'm calling `#get` and `#post` inside the method, which is the HTTP Method at the time of the request. You can also use `#patch` `#put` `#delete`.
|
87
87
|
|
88
88
|
### Pagination
|
89
89
|
|
@@ -116,7 +116,7 @@ For example, in the following response, `$.link.next` indicates `"https://exampl
|
|
116
116
|
{
|
117
117
|
"links": {
|
118
118
|
"next": "https://example.com/pagination?page=3",
|
119
|
-
"previous": "https://example.com/pagination?page=1"
|
119
|
+
"previous": "https://example.com/pagination?page=1"
|
120
120
|
},
|
121
121
|
"page": 2
|
122
122
|
}
|
@@ -216,13 +216,28 @@ In the above case, it matches JSON as below:
|
|
216
216
|
|
217
217
|
```json
|
218
218
|
{
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
219
|
+
"erros": {
|
220
|
+
"code": 10,
|
221
|
+
"message": "Some error has occurred."
|
222
|
+
}
|
223
223
|
}
|
224
224
|
```
|
225
225
|
|
226
|
+
For `headers`, specify response header for the Key of `Hash`, get an arbitrary value from the response header, and check whether it matches value. You can handle errors. You can specify `String` and `Regexp` for value.
|
227
|
+
|
228
|
+
```ruby
|
229
|
+
error_handling headers: { 'www-authenticate': /invalid token/ }, with: :my_error_handling
|
230
|
+
```
|
231
|
+
|
232
|
+
In the above case, it matches response header as below:
|
233
|
+
|
234
|
+
```text
|
235
|
+
cache-control: no-cache, no-store, max-age=0, must-revalidate
|
236
|
+
content-type: application/json
|
237
|
+
www-authenticate: Bearer error="invalid_token", error_description="invalid token"
|
238
|
+
content-length: 104
|
239
|
+
```
|
240
|
+
|
226
241
|
By specifying the instance method name in `with`, when an error is detected, any method can be executed before raising an exception. The arguments passed to the method are `params` and `logger` as in the `block` definition. Note that `block` and` with` cannot be used at the same time.
|
227
242
|
|
228
243
|
```ruby
|
@@ -335,8 +350,8 @@ error_handling json: { '$.errors.code': 20 },
|
|
335
350
|
|
336
351
|
Keep the following in mind when using the `retry` option:
|
337
352
|
|
338
|
-
|
339
|
-
|
353
|
+
- The `raise` option must be specified for `error_handling`
|
354
|
+
- Definition of `error_handling` using `block` is prohibited
|
340
355
|
|
341
356
|
#### MyApiClient::NetworkError
|
342
357
|
|
@@ -405,7 +420,6 @@ class ExampleApiClient < MyApiClient::Base
|
|
405
420
|
end
|
406
421
|
```
|
407
422
|
|
408
|
-
|
409
423
|
WIP
|
410
424
|
|
411
425
|
### Stubbing
|
@@ -24,4 +24,13 @@ module MyErrors
|
|
24
24
|
|
25
25
|
# Error code: other
|
26
26
|
class ErrorCodeOther < MyApiClient::ClientError; end
|
27
|
+
|
28
|
+
# Header: X-First-Header has invalid
|
29
|
+
class FirstHeaderIsInvalid < MyApiClient::ClientError; end
|
30
|
+
|
31
|
+
# Header: X-First-Header has nothing and status is 404
|
32
|
+
class FirstHeaderHasNothingAndNotFound < MyApiClient::ClientError; end
|
33
|
+
|
34
|
+
# Header: X-First-Header has unknown and X-Second-Header has error
|
35
|
+
class MultipleHeaderIsInvalid < MyApiClient::ClientError; end
|
27
36
|
end
|
@@ -0,0 +1,38 @@
|
|
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/header_controller.rb
|
7
|
+
class MyHeaderApiClient < ApplicationApiClient
|
8
|
+
error_handling headers: { 'X-First-Header': /invalid/ },
|
9
|
+
raise: MyErrors::FirstHeaderIsInvalid
|
10
|
+
|
11
|
+
error_handling headers: {
|
12
|
+
'X-First-Header': /unknown/,
|
13
|
+
'X-Second-Header': /error/,
|
14
|
+
},
|
15
|
+
raise: MyErrors::MultipleHeaderIsInvalid
|
16
|
+
|
17
|
+
error_handling headers: { 'X-First-Header': /nothing/ },
|
18
|
+
status_code: 404,
|
19
|
+
raise: MyErrors::FirstHeaderHasNothingAndNotFound
|
20
|
+
|
21
|
+
# GET header
|
22
|
+
#
|
23
|
+
# @param first_header [String] X-First-Header
|
24
|
+
# @param second_header [String] X-Second-Header
|
25
|
+
# @return [Sawyer::Resource]
|
26
|
+
def get_header(first_header:, second_header:)
|
27
|
+
get 'header', headers: headers, query: {
|
28
|
+
'X-First-Header': first_header,
|
29
|
+
'X-Second-Header': second_header,
|
30
|
+
}.compact
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def headers
|
36
|
+
{ 'Content-Type': 'application/json;charset=UTF-8' }
|
37
|
+
end
|
38
|
+
end
|
@@ -4,7 +4,7 @@ module MyApiClient
|
|
4
4
|
module ErrorHandling
|
5
5
|
# Generates an error handler proc (or symbol)
|
6
6
|
class Generator < ServiceAbstract
|
7
|
-
ARGUMENTS = %i[instance response status_code json with raise block].freeze
|
7
|
+
ARGUMENTS = %i[instance response status_code headers json with raise block].freeze
|
8
8
|
|
9
9
|
# @param options [Hash]
|
10
10
|
# Options for this generator
|
@@ -14,6 +14,8 @@ module MyApiClient
|
|
14
14
|
# The target of verifying
|
15
15
|
# @option status_code [String, Range, Integer, Regexp]
|
16
16
|
# Verifies response HTTP status code and raises error if matched
|
17
|
+
# @option headers [String, Regexp]
|
18
|
+
# Verifies response HTTP header and raises error if matched
|
17
19
|
# @option json [Hash, Symbol]
|
18
20
|
# Verifies response body as JSON and raises error if matched.
|
19
21
|
# If specified `:forbid_nil`, it forbid `nil` on response_body.
|
@@ -36,7 +38,8 @@ module MyApiClient
|
|
36
38
|
|
37
39
|
def call
|
38
40
|
return unless match?(_status_code, _response.status)
|
39
|
-
return unless
|
41
|
+
return unless match_headers?(_headers, _response.headers)
|
42
|
+
return unless match_body?(_json, _response.body)
|
40
43
|
|
41
44
|
generate_error_handler
|
42
45
|
end
|
@@ -102,7 +105,17 @@ module MyApiClient
|
|
102
105
|
end
|
103
106
|
end
|
104
107
|
|
105
|
-
def
|
108
|
+
def match_headers?(headers, response_headers)
|
109
|
+
return true if headers.nil?
|
110
|
+
return false if response_headers.blank?
|
111
|
+
|
112
|
+
headers.all? do |header_key, operator|
|
113
|
+
target = response_headers[header_key]
|
114
|
+
match?(operator, target)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def match_body?(json, response_body)
|
106
119
|
return true if json.nil?
|
107
120
|
return response_body.nil? if json == :forbid_nil
|
108
121
|
return false if response_body.blank?
|
@@ -21,9 +21,9 @@ module MyApiClient
|
|
21
21
|
# The request and response parameters
|
22
22
|
# @param original_error [StandardError]
|
23
23
|
# Some network error
|
24
|
-
def initialize(params, original_error)
|
24
|
+
def initialize(params = nil, original_error = nil)
|
25
25
|
@original_error = original_error
|
26
|
-
super params, original_error
|
26
|
+
super params, original_error&.message
|
27
27
|
end
|
28
28
|
|
29
29
|
# Returns contents as string for to be readable for human
|
@@ -37,7 +37,7 @@ module MyApiClient
|
|
37
37
|
#
|
38
38
|
# @return [Hash] Metadata for bugsnag
|
39
39
|
def metadata
|
40
|
-
super
|
40
|
+
super&.merge(original_error: original_error&.inspect)
|
41
41
|
end
|
42
42
|
end
|
43
43
|
end
|
data/lib/my_api_client/errors.rb
CHANGED
@@ -5,7 +5,7 @@ module MyApiClient
|
|
5
5
|
class Error < StandardError
|
6
6
|
attr_reader :params
|
7
7
|
|
8
|
-
delegate :metadata, to: :params
|
8
|
+
delegate :metadata, to: :params, allow_nil: true
|
9
9
|
alias to_bugsnag metadata
|
10
10
|
|
11
11
|
# Initialize the error class
|
@@ -14,7 +14,7 @@ module MyApiClient
|
|
14
14
|
# The request and response parameters
|
15
15
|
# @param error_message [String]
|
16
16
|
# The error description
|
17
|
-
def initialize(params, error_message = nil)
|
17
|
+
def initialize(params = nil, error_message = nil)
|
18
18
|
@params = params
|
19
19
|
super error_message
|
20
20
|
end
|
@@ -6,12 +6,12 @@ module MyApiClient
|
|
6
6
|
alias _original_initialize initialize
|
7
7
|
|
8
8
|
# Override MyApiClient::Error#initialize
|
9
|
-
def initialize(params, error_message = nil)
|
9
|
+
def initialize(params = nil, error_message = nil)
|
10
10
|
_original_initialize(params, error_message)
|
11
11
|
|
12
12
|
Bugsnag.leave_breadcrumb(
|
13
13
|
"#{self.class.name} occurred",
|
14
|
-
metadata
|
14
|
+
metadata&.transform_values(&:inspect),
|
15
15
|
Bugsnag::Breadcrumbs::ERROR_BREADCRUMB_TYPE
|
16
16
|
)
|
17
17
|
end
|
data/my_api/Gemfile
CHANGED
@@ -2,12 +2,12 @@
|
|
2
2
|
|
3
3
|
source 'https://rubygems.org'
|
4
4
|
|
5
|
-
gem 'jets'
|
5
|
+
gem 'jets', '~> 3.1.5'
|
6
6
|
|
7
7
|
gem 'dynomite'
|
8
8
|
|
9
9
|
# See: https://github.com/boltops-tools/jets/issues/523
|
10
|
-
gem 'nokogiri', '~> 1.
|
10
|
+
gem 'nokogiri', '~> 1.13.8'
|
11
11
|
|
12
12
|
# development and test groups are not bundled as part of the deployment
|
13
13
|
group :development, :test do
|