Skip to content

Commit 3580f4d

Browse files
committed
Retry requests on "Connection reset" and "Broken pipe" SocketException
1 parent 274c1f6 commit 3580f4d

File tree

2 files changed

+38
-2
lines changed

2 files changed

+38
-2
lines changed

src/main/java/com/treasuredata/client/TDRequestErrorHandler.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,8 +182,10 @@ else if (e instanceof SocketException) {
182182
// All known SocketException are retryable.
183183
return new TDClientSocketException(socketException);
184184
}
185-
else if (Objects.equals(socketException.getMessage(), "Socket closed")) {
186-
// okhttp can raise java.net.SocketException("Socket closed")
185+
else if (Objects.equals(socketException.getMessage(), "Broken pipe") ||
186+
Objects.equals(socketException.getMessage(), "Connection reset") ||
187+
Objects.equals(socketException.getMessage(), "Socket closed")) {
188+
// The underlying socket implementation used by OkHttp may throw these exceptions.
187189
return new TDClientSocketException(socketException);
188190
}
189191
else {

src/test/java/com/treasuredata/client/TDRequestErrorHandlerTest.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,16 @@
1313
import org.slf4j.Logger;
1414
import org.slf4j.LoggerFactory;
1515

16+
import java.net.SocketException;
1617
import java.time.Instant;
1718
import java.util.Date;
1819
import java.util.Optional;
1920

2021
import static org.hamcrest.MatcherAssert.assertThat;
22+
import static org.hamcrest.Matchers.instanceOf;
2123
import static org.hamcrest.Matchers.is;
2224
import static org.junit.jupiter.api.Assertions.assertFalse;
25+
import static org.junit.jupiter.api.Assertions.assertThrows;
2326

2427
/**
2528
*
@@ -96,4 +99,35 @@ public void testParseRetryAfterSeconds()
9699
Instant expected = Instant.ofEpochMilli(now).plusSeconds(120);
97100
assertThat(retryAfter, is(expected));
98101
}
102+
103+
@Test
104+
public void defaultExceptionResolverBrokenPipe()
105+
{
106+
SocketException socketException = new SocketException("Broken pipe");
107+
TDClientException result = TDRequestErrorHandler.defaultExceptionResolver(socketException);
108+
assertThat(result, instanceOf(TDClientSocketException.class));
109+
}
110+
111+
@Test
112+
public void defaultExceptionResolverConnectionReset()
113+
{
114+
SocketException socketException = new SocketException("Connection reset");
115+
TDClientException result = TDRequestErrorHandler.defaultExceptionResolver(socketException);
116+
assertThat(result, instanceOf(TDClientSocketException.class));
117+
}
118+
119+
@Test
120+
public void defaultExceptionResolverSocketClosed()
121+
{
122+
SocketException socketException = new SocketException("Socket closed");
123+
TDClientException result = TDRequestErrorHandler.defaultExceptionResolver(socketException);
124+
assertThat(result, instanceOf(TDClientSocketException.class));
125+
}
126+
127+
@Test
128+
public void defaultExceptionResolverUnknownSocketException()
129+
{
130+
SocketException socketException = new SocketException("Unknown socket error");
131+
assertThrows(TDClientSocketException.class, () -> TDRequestErrorHandler.defaultExceptionResolver(socketException));
132+
}
99133
}

0 commit comments

Comments
 (0)