3434 */
3535public abstract class QosException extends RuntimeException {
3636
37+ private final QosReason reason ;
38+
3739 // Not meant for external subclassing.
38- private QosException (String message ) {
40+ private QosException (String message , QosReason reason ) {
3941 super (message );
42+ this .reason = reason ;
4043 }
4144
42- private QosException (String message , Throwable cause ) {
45+ private QosException (String message , Throwable cause , QosReason reason ) {
4346 super (message , cause );
47+ this .reason = reason ;
48+ }
49+
50+ public final QosReason getReason () {
51+ return reason ;
4452 }
4553
4654 public abstract <T > T accept (Visitor <T > visitor );
@@ -61,13 +69,27 @@ public static Throttle throttle() {
6169 return new Throttle (Optional .empty ());
6270 }
6371
72+ /**
73+ * Like {@link #throttle()}, but includes a reason.
74+ */
75+ public static Throttle throttle (QosReason reason ) {
76+ return new Throttle (Optional .empty (), reason );
77+ }
78+
6479 /**
6580 * Like {@link #throttle()}, but includes a cause.
6681 */
6782 public static Throttle throttle (Throwable cause ) {
6883 return new Throttle (Optional .empty (), cause );
6984 }
7085
86+ /**
87+ * Like {@link #throttle()}, but includes a reason, and a cause.
88+ */
89+ public static Throttle throttle (QosReason reason , Throwable cause ) {
90+ return new Throttle (Optional .empty (), cause , reason );
91+ }
92+
7193 /**
7294 * Like {@link #throttle()}, but additionally requests that the client wait for at least the given duration before
7395 * retrying the request.
@@ -76,13 +98,27 @@ public static Throttle throttle(Duration duration) {
7698 return new Throttle (Optional .of (duration ));
7799 }
78100
101+ /**
102+ * Like {@link #throttle(Duration)}, but includes a reason.
103+ */
104+ public static Throttle throttle (QosReason reason , Duration duration ) {
105+ return new Throttle (Optional .of (duration ), reason );
106+ }
107+
79108 /**
80109 * Like {@link #throttle(Duration)}, but includes a cause.
81110 */
82111 public static Throttle throttle (Duration duration , Throwable cause ) {
83112 return new Throttle (Optional .of (duration ), cause );
84113 }
85114
115+ /**
116+ * Like {@link #throttle(Duration)}, but includes a reason, and a cause.
117+ */
118+ public static Throttle throttle (QosReason reason , Duration duration , Throwable cause ) {
119+ return new Throttle (Optional .of (duration ), cause , reason );
120+ }
121+
86122 /**
87123 * Returns a {@link RetryOther} exception indicating that the calling client should retry against the given node of
88124 * this service.
@@ -91,13 +127,27 @@ public static RetryOther retryOther(URL redirectTo) {
91127 return new RetryOther (redirectTo );
92128 }
93129
130+ /**
131+ * Like {@link #retryOther(URL)}, but includes a reason.
132+ */
133+ public static RetryOther retryOther (QosReason reason , URL redirectTo ) {
134+ return new RetryOther (redirectTo , reason );
135+ }
136+
94137 /**
95138 * Like {@link #retryOther(URL)}, but includes a cause.
96139 */
97140 public static RetryOther retryOther (URL redirectTo , Throwable cause ) {
98141 return new RetryOther (redirectTo , cause );
99142 }
100143
144+ /**
145+ * Like {@link #retryOther(URL)}, but includes a reason, and a cause.
146+ */
147+ public static RetryOther retryOther (QosReason reason , URL redirectTo , Throwable cause ) {
148+ return new RetryOther (redirectTo , cause , reason );
149+ }
150+
101151 /**
102152 * An exception indicating that (this node of) this service is currently unavailable and the client may try again at
103153 * a later time, possibly against a different node of this service.
@@ -106,24 +156,53 @@ public static Unavailable unavailable() {
106156 return new Unavailable ();
107157 }
108158
159+ /**
160+ * Like {@link #unavailable()}, but includes a reason.
161+ */
162+ public static Unavailable unavailable (QosReason reason ) {
163+ return new Unavailable (reason );
164+ }
165+
109166 /**
110167 * Like {@link #unavailable()}, but includes a cause.
111168 */
112169 public static Unavailable unavailable (Throwable cause ) {
113170 return new Unavailable (cause );
114171 }
115172
173+ /**
174+ * Like {@link #unavailable()}, but includes a reason, and a cause.
175+ */
176+ public static Unavailable unavailable (QosReason reason , Throwable cause ) {
177+ return new Unavailable (cause , reason );
178+ }
179+
116180 /** See {@link #throttle}. */
117181 public static final class Throttle extends QosException implements SafeLoggable {
182+ private static final QosReason DEFAULT_REASON = QosReason .of ("qos-throttle" );
183+
118184 private final Optional <Duration > retryAfter ;
119185
120186 private Throttle (Optional <Duration > retryAfter ) {
121- super ("Suggesting request throttling with optional retryAfter duration: " + retryAfter );
187+ super ("Suggesting request throttling with optional retryAfter duration: " + retryAfter , DEFAULT_REASON );
188+ this .retryAfter = retryAfter ;
189+ }
190+
191+ private Throttle (Optional <Duration > retryAfter , QosReason reason ) {
192+ super ("Suggesting request throttling with optional retryAfter duration: " + retryAfter , reason );
122193 this .retryAfter = retryAfter ;
123194 }
124195
125196 private Throttle (Optional <Duration > retryAfter , Throwable cause ) {
126- super ("Suggesting request throttling with optional retryAfter duration: " + retryAfter , cause );
197+ super (
198+ "Suggesting request throttling with optional retryAfter duration: " + retryAfter ,
199+ cause ,
200+ DEFAULT_REASON );
201+ this .retryAfter = retryAfter ;
202+ }
203+
204+ private Throttle (Optional <Duration > retryAfter , Throwable cause , QosReason reason ) {
205+ super ("Suggesting request throttling with optional retryAfter duration: " + retryAfter , cause , reason );
127206 this .retryAfter = retryAfter ;
128207 }
129208
@@ -149,15 +228,27 @@ public List<Arg<?>> getArgs() {
149228
150229 /** See {@link #retryOther}. */
151230 public static final class RetryOther extends QosException implements SafeLoggable {
231+ private static final QosReason DEFAULT_REASON = QosReason .of ("qos-retry-other" );
232+
152233 private final URL redirectTo ;
153234
154235 private RetryOther (URL redirectTo ) {
155- super ("Suggesting request retry against: " + redirectTo .toString ());
236+ super ("Suggesting request retry against: " + redirectTo .toString (), DEFAULT_REASON );
237+ this .redirectTo = redirectTo ;
238+ }
239+
240+ private RetryOther (URL redirectTo , QosReason reason ) {
241+ super ("Suggesting request retry against: " + redirectTo .toString (), reason );
156242 this .redirectTo = redirectTo ;
157243 }
158244
159245 private RetryOther (URL redirectTo , Throwable cause ) {
160- super ("Suggesting request retry against: " + redirectTo .toString (), cause );
246+ super ("Suggesting request retry against: " + redirectTo .toString (), cause , DEFAULT_REASON );
247+ this .redirectTo = redirectTo ;
248+ }
249+
250+ private RetryOther (URL redirectTo , Throwable cause , QosReason reason ) {
251+ super ("Suggesting request retry against: " + redirectTo .toString (), cause , reason );
161252 this .redirectTo = redirectTo ;
162253 }
163254
@@ -184,14 +275,24 @@ public List<Arg<?>> getArgs() {
184275
185276 /** See {@link #unavailable}. */
186277 public static final class Unavailable extends QosException implements SafeLoggable {
278+ private static final QosReason DEFAULT_REASON = QosReason .of ("qos-unavailable" );
279+
187280 private static final String SERVER_UNAVAILABLE = "Server unavailable" ;
188281
189282 private Unavailable () {
190- super (SERVER_UNAVAILABLE );
283+ super (SERVER_UNAVAILABLE , DEFAULT_REASON );
284+ }
285+
286+ private Unavailable (QosReason reason ) {
287+ super (SERVER_UNAVAILABLE , reason );
191288 }
192289
193290 private Unavailable (Throwable cause ) {
194- super (SERVER_UNAVAILABLE , cause );
291+ super (SERVER_UNAVAILABLE , cause , DEFAULT_REASON );
292+ }
293+
294+ private Unavailable (Throwable cause , QosReason reason ) {
295+ super (SERVER_UNAVAILABLE , cause , reason );
195296 }
196297
197298 @ Override
0 commit comments