Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion src/main/java/com/github/underscore/U.java
Original file line number Diff line number Diff line change
Expand Up @@ -2246,7 +2246,7 @@ public static FetchResponse fetch(
final java.io.ByteArrayOutputStream result = new java.io.ByteArrayOutputStream();
final byte[] buffer = new byte[BUFFER_LENGTH_1024];
int length;
while ((length = inputStream.read(buffer)) != -1) {
while ((length = readWithRetry(inputStream, buffer)) != -1) {
result.write(buffer, 0, length);
}
inputStream.close();
Expand All @@ -2260,6 +2260,18 @@ public static FetchResponse fetch(
}
}

public static int readWithRetry(java.io.InputStream inputStream, byte[] buffer) throws java.io.IOException {
java.io.IOException lastException = null;
for (int attempt = 0; attempt < 2; attempt++) {
try {
return inputStream.read(buffer);
} catch (java.io.IOException ex) {
lastException = ex;
}
}
throw lastException;
}

public static class Fetch {
private Fetch() {}

Expand Down
79 changes: 79 additions & 0 deletions src/test/java/com/github/underscore/LodashTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -763,6 +763,85 @@ void fetchPut() {
resultChain.item().replace("\r\n", "\n"));
}

static class TestInputStream extends java.io.InputStream {
private final int[] returnValues;
private final IOException[] exceptions;
private int callCount = 0;

public TestInputStream(int[] returnValues, IOException[] exceptions) {
this.returnValues = returnValues;
this.exceptions = exceptions;
}

@Override
public int read() {
return 0;
}

@Override
public int read(byte[] b) throws IOException {
int index = callCount++;
if (exceptions != null && index < exceptions.length && exceptions[index] != null) {
throw exceptions[index];
}
if (returnValues != null && index < returnValues.length) {
return returnValues[index];
}
return -1;
}
}

@Test
void testSuccessfulReadOnFirstAttempt() throws IOException {
java.io.InputStream inputStream = new TestInputStream(new int[]{100}, null);
byte[] buffer = new byte[1024];
int result = U.readWithRetry(inputStream, buffer);
assertEquals(100, result);
}

@Test
void testSuccessfulReadOnSecondAttempt() throws IOException {
java.io.InputStream inputStream = new TestInputStream(
new int[]{0, 50},
new IOException[]{new IOException("First failed"), null}
);
byte[] buffer = new byte[1024];
int result = U.readWithRetry(inputStream, buffer);
assertEquals(50, result);
}

@Test
void testBothAttemptsFailWithIOException() {
java.io.InputStream inputStream = new TestInputStream(
null,
new IOException[]{
new IOException("First attempt failed"),
new IOException("Second attempt failed")
}
);
byte[] buffer = new byte[1024];
IOException thrown = assertThrows(IOException.class, () -> {
U.readWithRetry(inputStream, buffer);
});
assertEquals("Second attempt failed", thrown.getMessage());
}

@Test
void testReadReturnsMinusOne() throws IOException {
java.io.InputStream inputStream = new TestInputStream(new int[]{-1}, null);
byte[] buffer = new byte[1024];
int result = U.readWithRetry(inputStream, buffer);
assertEquals(-1, result);
}

@Test
void testReadReturnsZero() throws IOException {
java.io.InputStream inputStream = new TestInputStream(new int[]{0}, null);
byte[] buffer = new byte[1024];
int result = U.readWithRetry(inputStream, buffer);
assertEquals(0, result);
}

@Test
void fetchWrongUrl() {
assertThrows(IllegalArgumentException.class, () -> U.fetch("ttt"));
Expand Down
Loading