Skip to content

Commit 105fe54

Browse files
Update ErrorDetails wrappers
1 parent e7e4990 commit 105fe54

File tree

1 file changed

+151
-2
lines changed

1 file changed

+151
-2
lines changed

Sources/GRPCProtobuf/Errors/ErrorDetails+Types.swift

Lines changed: 151 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,14 +205,116 @@ extension ErrorDetails {
205205
/// exceeded".
206206
public var violationDescription: String
207207

208-
public init(subject: String, description: String) {
208+
/// The API Service from which the `QuotaFailure.Violation` orginates. In
209+
/// some cases, Quota issues originate from an API Service other than the one
210+
/// that was called. In other words, a dependency of the called API Service
211+
/// could be the cause of the `QuotaFailure`, and this field would have the
212+
/// dependency API service name.
213+
///
214+
/// For example, if the called API is Kubernetes Engine API
215+
/// (container.googleapis.com), and a quota violation occurs in the
216+
/// Kubernetes Engine API itself, this field would be
217+
/// "container.googleapis.com". On the other hand, if the quota violation
218+
/// occurs when the Kubernetes Engine API creates VMs in the Compute Engine
219+
/// API (compute.googleapis.com), this field would be
220+
/// "compute.googleapis.com".
221+
public var apiService: String
222+
223+
/// The metric of the violated quota. A quota metric is a named counter to
224+
/// measure usage, such as API requests or CPUs. When an activity occurs in a
225+
/// service, such as Virtual Machine allocation, one or more quota metrics
226+
/// may be affected.
227+
///
228+
/// For example, "compute.googleapis.com/cpus_per_vm_family",
229+
/// "storage.googleapis.com/internet_egress_bandwidth".
230+
public var quotaMetric: String
231+
232+
/// The id of the violated quota. Also know as "limit name", this is the
233+
/// unique identifier of a quota in the context of an API service.
234+
///
235+
/// For example, "CPUS-PER-VM-FAMILY-per-project-region".
236+
public var quotaID: String
237+
238+
/// The dimensions of the violated quota. Every non-global quota is enforced
239+
/// on a set of dimensions. While quota metric defines what to count, the
240+
/// dimensions specify for what aspects the counter should be increased.
241+
///
242+
/// For example, the quota "CPUs per region per VM family" enforces a limit
243+
/// on the metric "compute.googleapis.com/cpus_per_vm_family" on dimensions
244+
/// "region" and "vm_family". And if the violation occurred in region
245+
/// "us-central1" and for VM family "n1", the quota_dimensions would be,
246+
///
247+
/// {
248+
/// "region": "us-central1",
249+
/// "vm_family": "n1",
250+
/// }
251+
///
252+
/// When a quota is enforced globally, the quota_dimensions would always be
253+
/// empty.
254+
public var quotaDimensions: [String: String]
255+
256+
/// The enforced quota value at the time of the `QuotaFailure`.
257+
///
258+
/// For example, if the enforced quota value at the time of the
259+
/// `QuotaFailure` on the number of CPUs is "10", then the value of this
260+
/// field would reflect this quantity.
261+
public var quotaValue: Int64
262+
263+
/// The new quota value being rolled out at the time of the violation. At the
264+
/// completion of the rollout, this value will be enforced in place of
265+
/// quota_value. If no rollout is in progress at the time of the violation,
266+
/// this field is not set.
267+
///
268+
/// For example, if at the time of the violation a rollout is in progress
269+
/// changing the number of CPUs quota from 10 to 20, 20 would be the value of
270+
/// this field.
271+
public var futureQuotaValue: Int64?
272+
273+
public init(
274+
subject: String,
275+
description: String,
276+
) {
209277
self.subject = subject
210278
self.violationDescription = description
279+
self.apiService = ""
280+
self.quotaMetric = ""
281+
self.quotaID = ""
282+
self.quotaDimensions = [:]
283+
self.quotaValue = 0
284+
self.futureQuotaValue = nil
285+
}
286+
287+
public init(
288+
subject: String,
289+
description: String,
290+
apiService: String,
291+
quotaMetric: String,
292+
quotaID: String,
293+
quotaDimensions: [String: String],
294+
quotaValue: Int64,
295+
futureQuotaValue: Int64?
296+
) {
297+
self.subject = subject
298+
self.violationDescription = description
299+
self.apiService = apiService
300+
self.quotaMetric = quotaMetric
301+
self.quotaID = quotaID
302+
self.quotaDimensions = quotaDimensions
303+
self.quotaValue = quotaValue
304+
self.futureQuotaValue = futureQuotaValue
211305
}
212306

213307
init(_ storage: Google_Rpc_QuotaFailure.Violation) {
214308
self.subject = storage.subject
215309
self.violationDescription = storage.description_p
310+
self.apiService = storage.apiService
311+
self.quotaMetric = storage.quotaMetric
312+
self.quotaID = storage.quotaID
313+
self.quotaDimensions = storage.quotaDimensions
314+
self.quotaValue = storage.quotaValue
315+
if storage.hasFutureQuotaValue {
316+
self.futureQuotaValue = storage.futureQuotaValue
317+
}
216318
}
217319
}
218320

@@ -225,6 +327,14 @@ extension ErrorDetails {
225327
.with {
226328
$0.subject = violation.subject
227329
$0.description_p = violation.violationDescription
330+
$0.apiService = violation.apiService
331+
$0.quotaMetric = violation.quotaMetric
332+
$0.quotaID = violation.quotaID
333+
$0.quotaDimensions = violation.quotaDimensions
334+
$0.quotaValue = violation.quotaValue
335+
if let futureQuotaValue = violation.futureQuotaValue {
336+
$0.futureQuotaValue = futureQuotaValue
337+
}
228338
}
229339
}
230340
}
@@ -368,14 +478,49 @@ extension ErrorDetails {
368478
/// A description of why the request element is bad.
369479
public var violationDescription: String
370480

371-
public init(field: String, description: String) {
481+
/// The reason of the field-level error. This is a constant value that
482+
/// identifies the proximate cause of the field-level error. It should
483+
/// uniquely identify the type of the FieldViolation within the scope of the
484+
/// google.rpc.ErrorInfo.domain. This should be at most 63
485+
/// characters and match a regular expression of `[A-Z][A-Z0-9_]+[A-Z0-9]`,
486+
/// which represents UPPER_SNAKE_CASE.
487+
public var reason: String
488+
489+
/// Provides a localized error message for field-level errors that is safe to
490+
/// return to the API consumer.
491+
public var localizedMessage: LocalizedMessage?
492+
493+
public init(
494+
field: String,
495+
description: String,
496+
) {
372497
self.field = field
373498
self.violationDescription = description
499+
self.reason = ""
500+
self.localizedMessage = nil
501+
}
502+
503+
public init(
504+
field: String,
505+
description: String,
506+
reason: String,
507+
localizedMessage: LocalizedMessage?
508+
) {
509+
self.field = field
510+
self.violationDescription = description
511+
self.reason = reason
512+
self.localizedMessage = localizedMessage
374513
}
375514

376515
init(_ storage: Google_Rpc_BadRequest.FieldViolation) {
377516
self.field = storage.field
378517
self.violationDescription = storage.description_p
518+
self.reason = storage.reason
519+
if storage.hasLocalizedMessage {
520+
self.localizedMessage = LocalizedMessage(storage: storage.localizedMessage)
521+
} else {
522+
self.localizedMessage = nil
523+
}
379524
}
380525
}
381526

@@ -388,6 +533,10 @@ extension ErrorDetails {
388533
.with {
389534
$0.field = violation.field
390535
$0.description_p = violation.violationDescription
536+
$0.reason = violation.reason
537+
if let localizedMessage = violation.localizedMessage {
538+
$0.localizedMessage = localizedMessage.storage
539+
}
391540
}
392541
}
393542
}

0 commit comments

Comments
 (0)