gapic-common 0.15.0 → 0.16.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5902b53f0f5a46b4682ff855fb89a6a3162af38523fa273f273abeeeed0d3a3d
4
- data.tar.gz: a1e9bb69d31725768f00b152efcaf29042657fbb304c2ba2f25de485831fe187
3
+ metadata.gz: 1e75598e117f5f4e8829498d534e4a9106ad28d60b49537e556c094bb73aec6d
4
+ data.tar.gz: cdbc7ea9f2135123e54cd65eaa964da0bac013a380a5517266666cb780fe272b
5
5
  SHA512:
6
- metadata.gz: 84d77cc3d943714b8a3578ecabf3fea3a321dfe0929ee108233d4dcd8fede90a37be21a81e121142739aa3dca102ffff0826a003906bec16f03749beddf59ab2
7
- data.tar.gz: 27e2815be724399a4c01ca1d47c7b2e9291ee4583018251f45a2a0162f1d5cd8298d0ca3b8a4cf90fc4ba6f2e410240439e61a22a66fbeae89c5a3e9dc223879
6
+ metadata.gz: 29a7d283e612f3b63771a00c4b9ef6dbfeed924fd49acde80296df0868af30e4dfa28644db6af5b79eb9a55466d6d583d583e4fd390b19c0fbcb4bf8241db795
7
+ data.tar.gz: e930d32eae8b3fd68ffc4452a2d9462c6f3ad762abc769a8eaef0df7a8f554d2a0c4b2e8b5c476dc82ee795382c869cba0e0ab765fe614558f945d8e938790c3
data/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Release History
2
2
 
3
+ ### 0.16.0 (2022-12-12)
4
+
5
+ #### Features
6
+
7
+ * custom regapic exception wrapping ([#866](https://github.com/googleapis/gapic-generator-ruby/issues/866))
8
+
9
+ ### 0.15.1 (2022-11-18)
10
+
11
+ #### Bug Fixes
12
+
13
+ * Fixed uninitialized constant when checking retry policy for a REST call ([#857](https://github.com/googleapis/gapic-generator-ruby/issues/857))
14
+
3
15
  ### 0.15.0 (2022-11-17)
4
16
 
5
17
  #### Features
@@ -45,26 +45,29 @@ module Gapic
45
45
  # @private
46
46
  ERROR_STRING_MAPPING = error_code_mapping.each_with_index.to_h.freeze
47
47
 
48
+ # @private
49
+ HTTP_GRPC_CODE_MAP = {
50
+ 400 => 3, # InvalidArgumentError
51
+ 401 => 16, # UnauthenticatedError
52
+ 403 => 7, # PermissionDeniedError
53
+ 404 => 5, # NotFoundError
54
+ 409 => 6, # AlreadyExistsError
55
+ 412 => 9, # FailedPreconditionError
56
+ 429 => 8, # ResourceExhaustedError
57
+ 499 => 1, # CanceledError
58
+ 500 => 13, # InternalError
59
+ 501 => 12, # UnimplementedError
60
+ 503 => 14, # UnavailableError
61
+ 504 => 4 # DeadlineExceededError
62
+ }.freeze
63
+
48
64
  # @private
49
65
  # Converts http error codes into corresponding gRPC ones
50
66
  def self.grpc_error_for http_error_code
51
67
  return 2 unless http_error_code
52
68
 
53
69
  # The http status codes mapped to their error classes.
54
- {
55
- 400 => 3, # InvalidArgumentError
56
- 401 => 16, # UnauthenticatedError
57
- 403 => 7, # PermissionDeniedError
58
- 404 => 5, # NotFoundError
59
- 409 => 6, # AlreadyExistsError
60
- 412 => 9, # FailedPreconditionError
61
- 429 => 8, # ResourceExhaustedError
62
- 499 => 1, # CanceledError
63
- 500 => 13, # InternalError
64
- 501 => 12, # UnimplementedError
65
- 503 => 14, # UnavailableError
66
- 504 => 4 # DeadlineExceededError
67
- }[http_error_code] || 2 # UnknownError
70
+ HTTP_GRPC_CODE_MAP[http_error_code] || 2 # UnknownError
68
71
  end
69
72
  end
70
73
  end
@@ -106,7 +106,7 @@ module Gapic
106
106
  private
107
107
 
108
108
  def retry? error
109
- (error.is_a?(::GRPC::BadStatus) && retry_codes.include?(error.code)) ||
109
+ (defined?(::GRPC) && error.is_a?(::GRPC::BadStatus) && retry_codes.include?(error.code)) ||
110
110
  (error.respond_to?(:response_status) &&
111
111
  retry_codes.include?(ErrorCodes.grpc_error_for(error.response_status)))
112
112
  end
@@ -14,6 +14,6 @@
14
14
 
15
15
  module Gapic
16
16
  module Common
17
- VERSION = "0.15.0".freeze
17
+ VERSION = "0.16.0".freeze
18
18
  end
19
19
  end
@@ -34,9 +34,15 @@ module Gapic
34
34
  # (see the [googleauth docs](https://googleapis.dev/ruby/googleauth/latest/index.html))
35
35
  # @param numeric_enums [Boolean] Whether to signal the server to JSON-encode enums as ints
36
36
  #
37
+ # @param raise_faraday_errors [Boolean]
38
+ # Whether to raise Faraday errors instead of wrapping them in `Gapic::Rest::Error`
39
+ # Added for backwards compatibility.
40
+ # Default is `true`. All REST clients (except for old versions of `google-cloud-compute-v1`)
41
+ # should explicitly set this parameter to `false`.
42
+ #
37
43
  # @yield [Faraday::Connection]
38
44
  #
39
- def initialize endpoint:, credentials:, numeric_enums: false
45
+ def initialize endpoint:, credentials:, numeric_enums: false, raise_faraday_errors: true
40
46
  @endpoint = endpoint
41
47
  @endpoint = "https://#{endpoint}" unless /^https?:/.match? endpoint
42
48
  @endpoint = @endpoint.sub %r{/$}, ""
@@ -44,6 +50,8 @@ module Gapic
44
50
  @credentials = credentials
45
51
  @numeric_enums = numeric_enums
46
52
 
53
+ @raise_faraday_errors = raise_faraday_errors
54
+
47
55
  @connection = Faraday.new url: @endpoint do |conn|
48
56
  conn.headers = { "Content-Type" => "application/json" }
49
57
  conn.request :google_authorization, @credentials unless @credentials.is_a? ::Symbol
@@ -137,35 +145,31 @@ module Gapic
137
145
  next_timeout = get_timeout deadline
138
146
 
139
147
  begin
140
- base_make_http_request(verb,
141
- uri: uri,
142
- body: body,
143
- params: params,
144
- metadata: options.metadata,
148
+ base_make_http_request(verb: verb, uri: uri, body: body,
149
+ params: params, metadata: options.metadata,
145
150
  timeout: next_timeout,
146
151
  is_server_streaming: is_server_streaming,
147
152
  &block)
153
+ rescue ::Faraday::TimeoutError => e
154
+ raise if @raise_faraday_errors
155
+ raise Gapic::Rest::DeadlineExceededError.wrap_faraday_error e, root_cause: retried_exception
148
156
  rescue ::Faraday::Error => e
149
157
  next_timeout = get_timeout deadline
150
158
 
151
- if next_timeout&.positive? && options.retry_policy.call(e)
159
+ if check_retry?(next_timeout) && options.retry_policy.call(e)
152
160
  retried_exception = e
153
161
  retry
154
162
  end
155
163
 
156
- unless next_timeout&.positive?
157
- raise Gapic::GRPC::DeadlineExceededError.new e.message, root_cause: retried_exception
158
- end
159
-
160
- raise e
164
+ raise if @raise_faraday_errors
165
+ raise ::Gapic::Rest::Error.wrap_faraday_error e
161
166
  end
162
167
  end
163
168
 
164
- private
165
-
166
169
  ##
167
170
  # @private
168
171
  # Sends a http request via Faraday
172
+ #
169
173
  # @param verb [Symbol] http verb
170
174
  # @param uri [String] uri to send this request to
171
175
  # @param body [String, nil] a body to send with the request, nil for requests without a body
@@ -174,7 +178,8 @@ module Gapic
174
178
  # @param is_server_streaming [Boolean] flag if method is streaming
175
179
  # @yieldparam chunk [String] The chunk of data received during server streaming.
176
180
  # @return [Faraday::Response]
177
- def base_make_http_request verb, uri:, body:, params:, metadata:, timeout:, is_server_streaming: false
181
+ def base_make_http_request verb:, uri:, body:, params:, metadata:,
182
+ timeout:, is_server_streaming: false
178
183
  if @numeric_enums && (!params.key?("$alt") || params["$alt"] == "json")
179
184
  params = params.merge({ "$alt" => "json;enum-encoding=int" })
180
185
  end
@@ -192,6 +197,14 @@ module Gapic
192
197
  end
193
198
  end
194
199
 
200
+ private
201
+
202
+ ##
203
+ # Calculates deadline
204
+ #
205
+ # @param options [Gapic::CallOptions] call options for this call
206
+ #
207
+ # @return [Numeric, nil] Deadline against a POSIX clock_gettime()
195
208
  def calculate_deadline options
196
209
  return if options.timeout.nil?
197
210
  return if options.timeout.negative?
@@ -199,10 +212,28 @@ module Gapic
199
212
  Process.clock_gettime(Process::CLOCK_MONOTONIC) + options.timeout
200
213
  end
201
214
 
215
+ ##
216
+ # Calculates timeout (seconds) to use as a Faraday timeout
217
+ #
218
+ # @param deadline [Numeric, nil] deadline
219
+ #
220
+ # @return [Numeric, nil] Timeout (seconds)
202
221
  def get_timeout deadline
203
222
  return if deadline.nil?
204
223
  deadline - Process.clock_gettime(Process::CLOCK_MONOTONIC)
205
224
  end
225
+
226
+ ##
227
+ # Whether the timeout should be retried
228
+ #
229
+ # @param timeout [Numeric, nil]
230
+ #
231
+ # @return [Boolean] whether the timeout should be retried
232
+ def check_retry? timeout
233
+ return true if timeout.nil?
234
+
235
+ timeout.positive?
236
+ end
206
237
  end
207
238
  end
208
239
  end
@@ -55,6 +55,17 @@ module Gapic
55
55
  #
56
56
  # @return [ Gapic::Rest::Error]
57
57
  def wrap_faraday_error err
58
+ message, status_code, status, details, headers = parse_faraday_error err
59
+ Gapic::Rest::Error.new message, status_code, status: status, details: details, headers: headers
60
+ end
61
+
62
+ ##
63
+ # @private
64
+ # Tries to get the error information from Faraday error
65
+ #
66
+ # @param err [Faraday::Error] the Faraday error to extract information from
67
+ # @return [Array(String, String, String, String, String)]
68
+ def parse_faraday_error err
58
69
  message = err.message
59
70
  status_code = err.response_status
60
71
  status = nil
@@ -67,7 +78,7 @@ module Gapic
67
78
  status_code = code unless code.nil?
68
79
  end
69
80
 
70
- Gapic::Rest::Error.new message, status_code, status: status, details: details, headers: headers
81
+ [message, status_code, status, details, headers]
71
82
  end
72
83
 
73
84
  private
@@ -133,5 +144,62 @@ module Gapic
133
144
  end
134
145
  end
135
146
  end
147
+
148
+ ##
149
+ # An error class that represents DeadlineExceeded error for Rest
150
+ # with an optional retry root cause.
151
+ #
152
+ # If the deadline for making a call was exceeded during the rest calls,
153
+ # this exception is thrown wrapping Faraday::TimeoutError.
154
+ #
155
+ # If there were other exceptions retried before that, the last one will be
156
+ # saved as a "root_cause".
157
+ #
158
+ # @!attribute [r] root_cause
159
+ # @return [Object, nil] The exception that was being retried
160
+ # when the Faraday::TimeoutError error occured.
161
+ #
162
+ class DeadlineExceededError < Error
163
+ attr_reader :root_cause
164
+
165
+ ##
166
+ # @private
167
+ # @param message [String, nil] error message
168
+ # @param status_code [Integer, nil] HTTP status code of this error
169
+ # @param status [String, nil] The text representation of status as parsed from the response body
170
+ # @param details [Object, nil] Details data of this error
171
+ # @param headers [Object, nil] Http headers data of this error
172
+ # @param root_cause [Object, nil] The exception that was being retried
173
+ # when the Faraday::TimeoutError occured.
174
+ #
175
+ def initialize message, status_code, status: nil, details: nil, headers: nil, root_cause: nil
176
+ super message, status_code, status: status, details: details, headers: headers
177
+ @root_cause = root_cause
178
+ end
179
+
180
+ class << self
181
+ ##
182
+ # @private
183
+ # This creates a new error message wrapping the Faraday's one. Additionally
184
+ # it tries to parse and set a detailed message and an error code from
185
+ # from the Google Cloud's response body
186
+ #
187
+ # @param err [Faraday::TimeoutError] the Faraday error to wrap
188
+ #
189
+ # @param root_cause [Object, nil] The exception that was being retried
190
+ # when the Faraday::TimeoutError occured.
191
+ #
192
+ # @return [ Gapic::Rest::DeadlineExceededError]
193
+ def wrap_faraday_error err, root_cause: nil
194
+ message, status_code, status, details, headers = parse_faraday_error err
195
+ Gapic::Rest::DeadlineExceededError.new message,
196
+ status_code,
197
+ status: status,
198
+ details: details,
199
+ headers: headers,
200
+ root_cause: root_cause
201
+ end
202
+ end
203
+ end
136
204
  end
137
205
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gapic-common
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.15.0
4
+ version: 0.16.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Google API Authors
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-11-18 00:00:00.000000000 Z
11
+ date: 2022-12-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday