2222import java .time .Duration ;
2323import java .util .concurrent .atomic .AtomicInteger ;
2424
25+ import org .assertj .core .api .ThrowingConsumer ;
2526import org .junit .jupiter .api .Test ;
2627import reactor .core .publisher .Flux ;
2728import reactor .core .publisher .Mono ;
@@ -56,6 +57,7 @@ void withSimpleInterceptor() {
5657 NonAnnotatedBean proxy = (NonAnnotatedBean ) pf .getProxy ();
5758
5859 assertThatIllegalStateException ().isThrownBy (() -> proxy .retryOperation ().block ())
60+ .satisfies (isRetryExhaustedException ())
5961 .withCauseInstanceOf (IOException .class ).havingCause ().withMessage ("6" );
6062 assertThat (target .counter .get ()).isEqualTo (6 );
6163 }
@@ -71,6 +73,7 @@ void withPostProcessorForMethod() {
7173 AnnotatedMethodBean target = (AnnotatedMethodBean ) AopProxyUtils .getSingletonTarget (proxy );
7274
7375 assertThatIllegalStateException ().isThrownBy (() -> proxy .retryOperation ().block ())
76+ .satisfies (isRetryExhaustedException ())
7477 .withCauseInstanceOf (IOException .class ).havingCause ().withMessage ("6" );
7578 assertThat (target .counter .get ()).isEqualTo (6 );
7679 }
@@ -86,12 +89,15 @@ void withPostProcessorForClass() {
8689 AnnotatedClassBean target = (AnnotatedClassBean ) AopProxyUtils .getSingletonTarget (proxy );
8790
8891 assertThatRuntimeException ().isThrownBy (() -> proxy .retryOperation ().block ())
92+ .satisfies (isReactiveException ())
8993 .withCauseInstanceOf (IOException .class ).havingCause ().withMessage ("3" );
9094 assertThat (target .counter .get ()).isEqualTo (3 );
9195 assertThatRuntimeException ().isThrownBy (() -> proxy .otherOperation ().block ())
96+ .satisfies (isReactiveException ())
9297 .withCauseInstanceOf (IOException .class );
9398 assertThat (target .counter .get ()).isEqualTo (4 );
9499 assertThatIllegalStateException ().isThrownBy (() -> proxy .overrideOperation ().blockFirst ())
100+ .satisfies (isRetryExhaustedException ())
95101 .withCauseInstanceOf (IOException .class );
96102 assertThat (target .counter .get ()).isEqualTo (6 );
97103 }
@@ -108,6 +114,7 @@ void adaptReactiveResultWithMinimalRetrySpec() {
108114
109115 // Should execute only 2 times, because maxAttempts=1 means 1 call + 1 retry
110116 assertThatIllegalStateException ().isThrownBy (() -> proxy .retryOperation ().block ())
117+ .satisfies (isRetryExhaustedException ())
111118 .withCauseInstanceOf (IOException .class ).havingCause ().withMessage ("2" );
112119 assertThat (target .counter .get ()).isEqualTo (2 );
113120 }
@@ -123,6 +130,7 @@ void adaptReactiveResultWithZeroDelayAndJitter() {
123130 ZeroDelayJitterBean proxy = (ZeroDelayJitterBean ) pf .getProxy ();
124131
125132 assertThatIllegalStateException ().isThrownBy (() -> proxy .retryOperation ().block ())
133+ .satisfies (isRetryExhaustedException ())
126134 .withCauseInstanceOf (IOException .class ).havingCause ().withMessage ("4" );
127135 assertThat (target .counter .get ()).isEqualTo (4 );
128136 }
@@ -138,6 +146,7 @@ void adaptReactiveResultWithJitterGreaterThanDelay() {
138146 JitterGreaterThanDelayBean proxy = (JitterGreaterThanDelayBean ) pf .getProxy ();
139147
140148 assertThatIllegalStateException ().isThrownBy (() -> proxy .retryOperation ().block ())
149+ .satisfies (ex -> assertThat (ex .getClass ().getSimpleName ()).isEqualTo ("RetryExhaustedException" ))
141150 .withCauseInstanceOf (IOException .class ).havingCause ().withMessage ("4" );
142151 assertThat (target .counter .get ()).isEqualTo (4 );
143152 }
@@ -153,6 +162,7 @@ void adaptReactiveResultWithFluxMultiValue() {
153162 FluxMultiValueBean proxy = (FluxMultiValueBean ) pf .getProxy ();
154163
155164 assertThatIllegalStateException ().isThrownBy (() -> proxy .retryOperation ().blockFirst ())
165+ .satisfies (isRetryExhaustedException ())
156166 .withCauseInstanceOf (IOException .class ).havingCause ().withMessage ("4" );
157167 assertThat (target .counter .get ()).isEqualTo (4 );
158168 }
@@ -184,11 +194,21 @@ void adaptReactiveResultWithImmediateFailure() {
184194 ImmediateFailureBean proxy = (ImmediateFailureBean ) pf .getProxy ();
185195
186196 assertThatIllegalStateException ().isThrownBy (() -> proxy .retryOperation ().block ())
197+ .satisfies (isRetryExhaustedException ())
187198 .withCauseInstanceOf (RuntimeException .class ).havingCause ().withMessage ("immediate failure" );
188199 assertThat (target .counter .get ()).isEqualTo (4 );
189200 }
190201
191202
203+ private static ThrowingConsumer <? super Throwable > isReactiveException () {
204+ return ex -> assertThat (ex .getClass ().getSimpleName ()).isEqualTo ("ReactiveException" );
205+ }
206+
207+ private static ThrowingConsumer <? super Throwable > isRetryExhaustedException () {
208+ return ex -> assertThat (ex .getClass ().getSimpleName ()).isEqualTo ("RetryExhaustedException" );
209+ }
210+
211+
192212 static class NonAnnotatedBean {
193213
194214 AtomicInteger counter = new AtomicInteger ();
0 commit comments