Skip to content

Commit 1efa603

Browse files
RomehRobWin
authored andcommitted
Rx retry exclude error#317 (ReactiveX#372)
* Add response predicate to retry sync and async for enhancement ReactiveX#259 * ReactiveX#317 skipping Java Error type from onError Rx retry transformer * ReactiveX#317 adding proper comment
1 parent 13ef4be commit 1efa603

File tree

2 files changed

+90
-15
lines changed

2 files changed

+90
-15
lines changed

resilience4j-rxjava2/src/main/java/io/github/resilience4j/retry/transformer/RetryTransformer.java

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,24 @@
1616

1717
package io.github.resilience4j.retry.transformer;
1818

19-
import io.github.resilience4j.retry.Retry;
20-
import io.reactivex.*;
2119
import org.reactivestreams.Publisher;
2220

21+
import io.github.resilience4j.retry.Retry;
22+
import io.reactivex.Completable;
23+
import io.reactivex.CompletableSource;
24+
import io.reactivex.CompletableTransformer;
25+
import io.reactivex.Flowable;
26+
import io.reactivex.FlowableTransformer;
27+
import io.reactivex.Maybe;
28+
import io.reactivex.MaybeSource;
29+
import io.reactivex.MaybeTransformer;
30+
import io.reactivex.Observable;
31+
import io.reactivex.ObservableSource;
32+
import io.reactivex.ObservableTransformer;
33+
import io.reactivex.Single;
34+
import io.reactivex.SingleSource;
35+
import io.reactivex.SingleTransformer;
36+
2337
public class RetryTransformer<T> implements FlowableTransformer<T, T>, ObservableTransformer<T, T>,
2438
SingleTransformer<T, T>, CompletableTransformer, MaybeTransformer<T, T> {
2539
private final Retry retry;
@@ -102,10 +116,14 @@ void throwExceptionToForceRetryOnResult(T value) {
102116

103117
void onError(Throwable throwable) throws Exception {
104118
if (throwable instanceof RetryDueToResultException) return;
119+
// Filter Error to not retry on it
120+
if (throwable instanceof Error) {
121+
throw (Error) throwable;
122+
}
105123
try {
106124
context.onError(castToException(throwable));
107-
} catch (Throwable throwable1) {
108-
throw castToException(throwable);
125+
} catch (Throwable t) {
126+
throw castToException(t);
109127
}
110128
}
111129

resilience4j-rxjava2/src/test/java/io/github/resilience4j/retry/transformer/RetryTransformerTest.java

Lines changed: 68 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,28 @@
1616

1717
package io.github.resilience4j.retry.transformer;
1818

19-
import io.github.resilience4j.retry.Retry;
20-
import io.github.resilience4j.retry.RetryConfig;
21-
import io.github.resilience4j.test.HelloWorldService;
22-
import io.reactivex.*;
19+
import static org.assertj.core.api.Assertions.assertThat;
20+
import static org.mockito.BDDMockito.given;
21+
import static org.mockito.Mockito.doNothing;
22+
import static org.mockito.Mockito.doThrow;
23+
24+
import java.io.IOException;
25+
26+
import javax.xml.ws.WebServiceException;
27+
2328
import org.junit.Before;
2429
import org.junit.Test;
2530
import org.mockito.BDDMockito;
2631
import org.mockito.Mockito;
2732

28-
import javax.xml.ws.WebServiceException;
29-
import java.io.IOException;
30-
31-
import static org.assertj.core.api.Assertions.assertThat;
32-
import static org.mockito.BDDMockito.given;
33-
import static org.mockito.Mockito.doNothing;
34-
import static org.mockito.Mockito.doThrow;
33+
import io.github.resilience4j.retry.Retry;
34+
import io.github.resilience4j.retry.RetryConfig;
35+
import io.github.resilience4j.test.HelloWorldService;
36+
import io.reactivex.Completable;
37+
import io.reactivex.Flowable;
38+
import io.reactivex.Maybe;
39+
import io.reactivex.Observable;
40+
import io.reactivex.Single;
3541

3642
public class RetryTransformerTest {
3743

@@ -80,6 +86,57 @@ public void returnOnCompleteUsingSingle() {
8086
assertThat(metrics.getNumberOfFailedCallsWithoutRetryAttempt()).isEqualTo(0);
8187
}
8288

89+
90+
@Test(expected = StackOverflowError.class)
91+
public void shouldNotRetryUsingSingleStackOverFlow() {
92+
//Given
93+
RetryConfig config = RetryConfig.ofDefaults();
94+
Retry retry = Retry.of("testName", config);
95+
RetryTransformer<Object> retryTransformer = RetryTransformer.of(retry);
96+
97+
given(helloWorldService.returnHelloWorld())
98+
.willThrow(new StackOverflowError("BAM!"));
99+
100+
//When
101+
Single.fromCallable(helloWorldService::returnHelloWorld)
102+
.compose(retryTransformer)
103+
.test();
104+
105+
106+
//Then
107+
BDDMockito.then(helloWorldService).should(Mockito.times(1)).returnHelloWorld();
108+
Retry.Metrics metrics = retry.getMetrics();
109+
110+
assertThat(metrics.getNumberOfFailedCallsWithoutRetryAttempt()).isEqualTo(0);
111+
assertThat(metrics.getNumberOfFailedCallsWithRetryAttempt()).isEqualTo(0);
112+
}
113+
114+
@Test
115+
public void shouldNotRetryWhenItThrowErrorSingle() {
116+
//Given
117+
RetryConfig config = RetryConfig.ofDefaults();
118+
Retry retry = Retry.of("testName", config);
119+
RetryTransformer<Object> retryTransformer = RetryTransformer.of(retry);
120+
121+
given(helloWorldService.returnHelloWorld())
122+
.willThrow(new Error("BAM!"));
123+
124+
//When
125+
Single.fromCallable(helloWorldService::returnHelloWorld)
126+
.compose(retryTransformer)
127+
.test()
128+
.assertError(Error.class)
129+
.assertNotComplete()
130+
.assertSubscribed();
131+
//Then
132+
BDDMockito.then(helloWorldService).should(Mockito.times(1)).returnHelloWorld();
133+
Retry.Metrics metrics = retry.getMetrics();
134+
135+
assertThat(metrics.getNumberOfFailedCallsWithRetryAttempt()).isEqualTo(0);
136+
assertThat(metrics.getNumberOfFailedCallsWithoutRetryAttempt()).isEqualTo(0);
137+
}
138+
139+
83140
@Test
84141
public void returnOnErrorUsingSingle() {
85142
//Given

0 commit comments

Comments
 (0)