• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2022 Google LLC
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google LLC nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 package com.google.api.gax.rpc;
31 
32 import com.google.auto.value.AutoValue;
33 import com.google.common.annotations.VisibleForTesting;
34 import com.google.protobuf.Any;
35 import com.google.protobuf.InvalidProtocolBufferException;
36 import com.google.protobuf.Message;
37 import com.google.rpc.BadRequest;
38 import com.google.rpc.DebugInfo;
39 import com.google.rpc.ErrorInfo;
40 import com.google.rpc.Help;
41 import com.google.rpc.LocalizedMessage;
42 import com.google.rpc.PreconditionFailure;
43 import com.google.rpc.QuotaFailure;
44 import com.google.rpc.RequestInfo;
45 import com.google.rpc.ResourceInfo;
46 import com.google.rpc.RetryInfo;
47 import java.util.List;
48 import javax.annotation.Nullable;
49 
50 /** This class contains a list of standard error messages that returns from server. */
51 @AutoValue
52 public abstract class ErrorDetails {
53 
54   /**
55    * This is the most important and special error message. It describes the cause of the error with
56    * structured details that both humans and applications can depend on.
57    */
58   @Nullable
getErrorInfo()59   public ErrorInfo getErrorInfo() {
60     return unpack(ErrorInfo.class);
61   }
62 
63   /**
64    * Describes when the clients can retry a failed request. Clients could ignore the recommendation
65    * here or retry when this information is missing from error responses.
66    */
67   @Nullable
getRetryInfo()68   public RetryInfo getRetryInfo() {
69     return unpack(RetryInfo.class);
70   }
71 
72   /** Describes additional debugging info. */
73   @Nullable
getDebugInfo()74   public DebugInfo getDebugInfo() {
75     return unpack(DebugInfo.class);
76   }
77 
78   /** Describes how a quota check failed. */
79   @Nullable
getQuotaFailure()80   public QuotaFailure getQuotaFailure() {
81     return unpack(QuotaFailure.class);
82   }
83 
84   /** Describes what preconditions have failed. */
85   @Nullable
getPreconditionFailure()86   public PreconditionFailure getPreconditionFailure() {
87     return unpack(PreconditionFailure.class);
88   }
89 
90   /**
91    * Describes violations in a client request. This error type focuses on the syntactic aspects of
92    * the request.
93    */
94   @Nullable
getBadRequest()95   public BadRequest getBadRequest() {
96     return unpack(BadRequest.class);
97   }
98 
99   /**
100    * Contains metadata about the request that clients can attach when filing a bug or providing
101    * other forms of feedback.
102    */
103   @Nullable
getRequestInfo()104   public RequestInfo getRequestInfo() {
105     return unpack(RequestInfo.class);
106   }
107 
108   /** Describes the resource that is being accessed. */
109   @Nullable
getResourceInfo()110   public ResourceInfo getResourceInfo() {
111     return unpack(ResourceInfo.class);
112   }
113 
114   /** Provides links to documentation or for performing an out-of-band action. */
115   @Nullable
getHelp()116   public Help getHelp() {
117     return unpack(Help.class);
118   }
119 
120   /**
121    * Provides a localized error message that is safe to return to the user which can be attached to
122    * an RPC error
123    */
124   @Nullable
getLocalizedMessage()125   public LocalizedMessage getLocalizedMessage() {
126     return unpack(LocalizedMessage.class);
127   }
128 
129   /** This is a list of raw/unparsed error messages that returns from server. */
130   @Nullable
getRawErrorMessages()131   abstract List<Any> getRawErrorMessages();
132 
builder()133   public static Builder builder() {
134     return new AutoValue_ErrorDetails.Builder();
135   }
136 
137   @AutoValue.Builder
138   public abstract static class Builder {
139 
setRawErrorMessages(List<Any> rawErrorMessages)140     public abstract Builder setRawErrorMessages(List<Any> rawErrorMessages);
141 
build()142     public abstract ErrorDetails build();
143   }
144 
145   @VisibleForTesting
unpack(Class<T> errorTypeClazz)146   <T extends Message> T unpack(Class<T> errorTypeClazz) {
147     List<Any> rawErrorMessages = getRawErrorMessages();
148     if (rawErrorMessages == null) {
149       return null;
150     }
151     for (Any detail : rawErrorMessages) {
152       if (!detail.is(errorTypeClazz)) {
153         continue;
154       }
155       try {
156         return detail.unpack(errorTypeClazz);
157       } catch (InvalidProtocolBufferException e) {
158         throw new ProtocolBufferParsingException(
159             String.format(
160                 "Failed to unpack %s from raw error messages", errorTypeClazz.getSimpleName()),
161             e);
162       }
163     }
164     return null;
165   }
166 }
167