Skip to content

Commit 15ab5d4

Browse files
committed
AutoCloseInputStream does not call handleIOException() on close()
1 parent ecbef78 commit 15ab5d4

4 files changed

Lines changed: 42 additions & 4 deletions

File tree

src/changes/changes.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ The <action> type attribute can be add,update,fix,remove.
8383
<action dev="ggregory" type="fix" due-to="Gary Gregory">RandomAccessFileInputStream.read() should return -1 (EOF) after the stream is closed.</action>
8484
<action dev="ggregory" type="fix" due-to="Gary Gregory">ReaderInputStream.available() should return 0 after the stream is closed.</action>
8585
<action dev="ggregory" type="fix" due-to="Gary Gregory">ReaderInputStream.read() should return -1 (EOF) after the stream is closed.</action>
86+
<action dev="ggregory" type="fix" due-to="Gary Gregory">AutoCloseInputStream does not call handleIOException() on close().</action>
8687
<!-- UPDATE -->
8788
<action dev="ggregory" type="update" due-to="Dependabot">Bump tests commons.bytebuddy.version from 1.14.13 to 1.14.18 #615, #621, #631, #635, #642.</action>
8889
<action dev="ggregory" type="update" due-to="Dependabot">Bump tests commons-codec:commons-codec from 1.16.1 to 1.17.0.</action>

src/main/java/org/apache/commons/io/input/AutoCloseInputStream.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ protected void afterRead(final int n) throws IOException {
140140
*/
141141
@Override
142142
public void close() throws IOException {
143-
in.close();
143+
super.close();
144144
in = ClosedInputStream.INSTANCE;
145145
}
146146

src/main/java/org/apache/commons/io/input/ProxyInputStream.java

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.io.InputStream;
2424

2525
import org.apache.commons.io.IOUtils;
26+
import org.apache.commons.io.function.IOConsumer;
2627

2728
/**
2829
* A proxy stream which acts as a {@link FilterInputStream}, by passing all method calls on to the proxied stream, not changing which methods are called.
@@ -47,14 +48,33 @@ public abstract class ProxyInputStream extends FilterInputStream {
4748
*/
4849
private boolean closed;
4950

51+
/**
52+
* Handles exceptions.
53+
*/
54+
private final IOConsumer<IOException> exceptionHandler;
55+
5056
/**
5157
* Constructs a new ProxyInputStream.
5258
*
53-
* @param proxy the InputStream to delegate to
59+
* @param proxy the InputStream to proxy.
5460
*/
5561
public ProxyInputStream(final InputStream proxy) {
62+
// the proxy is stored in a protected superclass variable named 'in'
63+
this(proxy, e -> {
64+
throw e;
65+
});
66+
}
67+
68+
/**
69+
* Constructs a new ProxyInputStream for testing.
70+
*
71+
* @param proxy the InputStream to proxy.
72+
* @param exceptionHandler the exception handler.
73+
*/
74+
ProxyInputStream(final InputStream proxy, final IOConsumer<IOException> exceptionHandler) {
5675
// the proxy is stored in a protected superclass variable named 'in'
5776
super(proxy);
77+
this.exceptionHandler = exceptionHandler;
5878
}
5979

6080
/**
@@ -147,7 +167,7 @@ public void close() throws IOException {
147167
* @since 2.0
148168
*/
149169
protected void handleIOException(final IOException e) throws IOException {
150-
throw e;
170+
exceptionHandler.accept(e);
151171
}
152172

153173
/**

src/test/java/org/apache/commons/io/input/AutoCloseInputStreamTest.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
import static org.junit.jupiter.api.Assertions.assertFalse;
2121
import static org.junit.jupiter.api.Assertions.assertThrows;
2222
import static org.junit.jupiter.api.Assertions.assertTrue;
23+
import static org.mockito.Mockito.spy;
24+
import static org.mockito.Mockito.verify;
2325

2426
import java.io.ByteArrayInputStream;
2527
import java.io.IOException;
@@ -46,7 +48,7 @@ public void setUp() {
4648
data = new byte[] { 'x', 'y', 'z' };
4749
stream = new AutoCloseInputStream(new ByteArrayInputStream(data) {
4850
@Override
49-
public void close() {
51+
public void close() throws IOException {
5052
closed = true;
5153
}
5254
});
@@ -90,7 +92,22 @@ public void testBuilderGet() {
9092
public void testClose() throws IOException {
9193
stream.close();
9294
assertTrue(closed, "closed");
95+
assertTrue(stream.isClosed(), "closed");
9396
assertEquals(-1, stream.read(), "read()");
97+
assertTrue(stream.isClosed(), "closed");
98+
}
99+
100+
@SuppressWarnings("resource")
101+
@Test
102+
public void testCloseHandleIOException() throws IOException {
103+
final IOException exception = new IOException();
104+
@SuppressWarnings({ "deprecation" })
105+
final ProxyInputStream inputStream = AutoCloseInputStream.builder().setInputStream(new BrokenInputStream(exception)).get();
106+
assertFalse(inputStream.isClosed(), "closed");
107+
final ProxyInputStream spy = spy(inputStream);
108+
assertThrows(IOException.class, spy::close);
109+
verify(spy).handleIOException(exception);
110+
assertFalse(spy.isClosed(), "closed");
94111
}
95112

96113
@Test

0 commit comments

Comments
 (0)