UncheckedIOException and suppressed exception
Peter Levart
peter.levart at gmail.com
Sat Feb 9 07:47:51 PST 2013
On 02/08/2013 03:38 PM, Zhong Yu wrote:
> On Tue, Feb 5, 2013 at 3:47 AM, Peter Levart<peter.levart at gmail.com> wrote:
>
>> try (CloseableStream<Path> = ...) {
>> try {
>> ... direct Path operations throwing IOException and/or
>> ... Stream<Path> operations throwing UncheckedIOException
>> }
>> catch (UncheckedIOException uioe) { throw uioe.getCause(); }
>> }
>> catch (EOFException eofe) {
>> // ...
>> }
>> catch (ZipException ze) {
>> // ...
>> }
>> catch (IOException ioe) {
>> //...
>> }
> There's a bug - the exception from CloseableStream escapes handling
> and creeps away.
>
> Since closing is hidden in a try-with-resource statement, people often
> forget about it, therefore close() should throw the same type of
> exception as opening. If CloseableStream.close() throws IOException,
> the bug won't exist.
Hi Zhong,
That's true. And that would be dangerous for AutoCloseable resources
that "buffer" output and "flush" it when closed. But Stream<Path> or any
potential CloseableStream seems to be an inherently "input" resource. Is
it really possible that closing an open directory fails on any OS? I
think that CloseableStream could thrown an IOError in that case,
indicating that there is really something wrong with the platform logic
or the state of OS. The linux closedir specifies the following for example:
RETURN VALUE
The closedir() function returns 0 on success. On error, -1 is
returned, and errno is set appropriately.
ERRORS
EBADF Invalid directory stream descriptor dirp.
...such error should really not occur...
> I'm still at the position that opening/closing the stream should throw
> UncheckedIOException, so that the entire try-with-resource statement
> throws a consistent exception type.
>
> try(stream = openStream())
> using stream
> catch(UncheckedIOException e)
> handle e
>
> I'm not convinced that "using stream" could involve IOException; why
> would one call Files.list() to get a Stream<Path>, then turn it into
> Iterator<Path> to operate on files "in the open", why he could simply
> use the good old Files.newDirectoryStream()?
Might be just to filter the files using lambdas? But I agree that most
of the times the processing of Paths would be done inside the Streams
API too. I would do it that way...
If all IOExceptions were consistently wrapped with UncheckedIOExceptions
then when one wanted to deal with several IOException subtypes, (s)he
would have to do the unwrapping in the handler at the end of
try-with-resources, like for example the following:
try (CloseableStream<Path> = ...) {
... Stream<Path> operations throwing UncheckedIOException
}
catch (UncheckedIOException uioe) {
try {
throw uioe.getCause();
}
catch (EOFException eofe) {
// ...
}
catch (ZipException ze) {
// ...
}
catch (IOException ioe) {
//...
}
}
Not bad but not any better either. Only when it doesn't matter which
kind of IOException is thrown, the consistent wrapping with
UncheckedIOException simplifies things. I think it would be necessary to
try to write some real-world examples, like you proposed, to establish
the right attitude.
Regards, Peter
> Zhong Yu
More information about the lambda-dev
mailing list