Skip to content

Make InputStreamConsumer to be able to throw IOException #430

@mike-neck

Description

@mike-neck

ResourceList#forEachInputStream has the ignoreIOException and really handles IOException as such, but InputStreamConsumer#accept has no method signature to throw IOException.

Expected Behaviour

  • IOException can be thrown from InputStreamConsumer.
  • ResourceList#forEachInputStream can catch IOException thrown from InputStreamConsumer.
  • If true as the ignoreIOExceptions options is given to ResourceList#forEachInputStream method, an exceptions thrown from InputStreamConsumer will be ignored.

Actual Behaviour

  • InputStreamConsumer#accept has no method signature to throw IOException.
  • Users should surround with there IO operation code with try/catch and rethrow IOException wrapped with UncheckedIOException or any other RuntimeException.
  • But UncheckedIOExceptions or any other RuntimeExceptions won't be catched in forEachInputStream method.
  • The ignoreIOExceptions option will be ignored.

public void forEachInputStream(final InputStreamConsumer inputStreamConsumer,
final boolean ignoreIOExceptions) {
for (final Resource resource : this) {
try {
inputStreamConsumer.accept(resource, resource.open());
} catch (final IOException e) {
if (!ignoreIOExceptions) {
throw new IllegalArgumentException("Could not load resource " + resource, e);
}
} finally {
resource.close();
}
}
}

/** A {@link FunctionalInterface} for consuming the contents of a {@link Resource} as an {@link InputStream}. */
@FunctionalInterface
public interface InputStreamConsumer {
/**
* Consume a {@link Resource} as an {@link InputStream}.
*
* @param resource
* The {@link Resource} used to open the {@link InputStream}.
* @param inputStream
* The {@link InputStream} opened on the resource.
*/
void accept(final Resource resource, final InputStream inputStream);
}

Reporduce Code

The following code gives a compile error.

try (ScanResult scanResult = new ClassGraph()
    .scan()) {
  scanResult.getAllResources()
  .forEachInputStream((resource, inputStream) -> {
    throw new IOException("test");
  }, true);
}

The compilation error can be eliminated, but UncheckedIOException won't be ignored.

try (ScanResult scanResult = new ClassGraph()
    .scan()) {
  scanResult.getAllResources()
  .forEachInputStream((resource, inputStream) -> {
    try {
      throw new IOException("test");
    } catch (IOException e) {
      throw new UncheckedIOException(e);
    }
  }, true);
}

Other methods

ResourceList#forEachByteBuffer has the same problem. IOException cannot be thrown from ByteBufferConsumer, but only IOException can be ignored.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions