gapic-common 0.15.0 → 0.16.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 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