2020import com .palantir .logsafe .SafeArg ;
2121import com .palantir .logsafe .SafeLoggable ;
2222import java .net .URL ;
23+ import java .time .Duration ;
2324import java .util .ArrayList ;
2425import java .util .List ;
26+ import java .util .Optional ;
2527
2628/**
2729 * An exception raised by a service to indicate a potential Quality-of-Service problem, specifically requesting that the
3234public abstract class QosException extends RuntimeException {
3335
3436 // Not meant for external subclassing.
35- private QosException () {}
37+ private QosException (String message ) {
38+ super (message );
39+ }
3640
3741 abstract <T > T accept (Visitor <T > visitor );
3842
@@ -47,7 +51,15 @@ public interface Visitor<T> {
4751 * may retry against an arbitrary node of this service.
4852 */
4953 public static Throttle throttle () {
50- return new Throttle ();
54+ return new Throttle (Optional .empty ());
55+ }
56+
57+ /**
58+ * Like {@link #throttle()}, but additionally requests that the client wait for at least the given duration before
59+ * retrying the request.
60+ */
61+ public static Throttle throttle (Duration duration ) {
62+ return new Throttle (Optional .of (duration ));
5163 }
5264
5365 /**
@@ -59,16 +71,25 @@ public static RetryOther retryOther(URL redirectTo) {
5971 }
6072
6173 /**
62- * An exception indicating that (this node of) this service are currently unavailable and the client may try again
63- * at a later time, possibly against a different node of this service.
74+ * An exception indicating that (this node of) this service is currently unavailable and the client may try again at
75+ * a later time, possibly against a different node of this service.
6476 */
6577 public static Unavailable unavailable () {
6678 return new Unavailable ();
6779 }
6880
6981 /** See {@link #throttle}. */
7082 public static final class Throttle extends QosException {
71- private Throttle () {}
83+ private final Optional <Duration > retryAfter ;
84+
85+ private Throttle (Optional <Duration > retryAfter ) {
86+ super ("Suggesting request throttling with optional retryAfter duration: " + retryAfter );
87+ this .retryAfter = retryAfter ;
88+ }
89+
90+ public Optional <Duration > getRetryAfter () {
91+ return retryAfter ;
92+ }
7293
7394 @ Override
7495 <T > T accept (Visitor <T > visitor ) {
@@ -81,6 +102,7 @@ public static final class RetryOther extends QosException implements SafeLoggabl
81102 private final URL redirectTo ;
82103
83104 private RetryOther (URL redirectTo ) {
105+ super ("Suggesting request retry against: " + redirectTo .toString ());
84106 this .redirectTo = redirectTo ;
85107 }
86108
@@ -109,7 +131,9 @@ public List<Arg<?>> getArgs() {
109131
110132 /** See {@link #unavailable}. */
111133 public static final class Unavailable extends QosException {
112- private Unavailable () {}
134+ private Unavailable () {
135+ super ("Server unavailable" );
136+ }
113137
114138 @ Override
115139 <T > T accept (Visitor <T > visitor ) {
0 commit comments