3

I write to socket with:

OutputStream socketStream = socket.getOutputStream();
socketStream.write(buf);

But this can throw IOException, so I do:

try {
  OutputStream socketStream = socket.getOutputStream();
  socketStream.write(buf);
} catch (IOException e) {
  // logging
} finally {
  socket.close();
}
  1. But socket.close also force me to catch IOException! So do I need try ... catch it again in finally?

  2. When catch IOException from close, it mean socket not closed? So try close again? Or what to do?

Thanks

2 Answers 2

5

close() throws IOException because closing something usually implies calling flush(), and flushing might fail. For example, if you lose network connectivity and issue socket.close(), you cannot flush whatever you have buffered, so flush() will throw an exception. Because data might be lost, the exception is checked, so you are forced to deal with that possibility.

I think the best way to deal with this is:

try {
    OutputStream socketStream = socket.getOutputStream();
    socketStream.write(buf);
    socket.close();
} catch (IOException e) {
    // try to deal with your I/O error; do logging
} finally {
    closeSilently(socket);
}
...
// Somewhere else, usually part of an utility JAR like Apache Commons IO
public static void closeSilently(Socket s) {
    if (socket != null) {
        try {
            socket.close();
        } catch (IOException e2) {
            // do more logging if appropiate
        }
    }
}

This code will work normally in the common case. If something goes wrong (even inside close()), it will allow you to catch the exception and do something before unconditionally closing your socket and swallowing everything it might throw.

Sign up to request clarification or add additional context in comments.

2 Comments

What if socket passed to closeSilently is opened with error (i.e. connect failed), is safe call close on it? i think it won't be null
It should be safe. In most sane APIs, calling close()is a no-op when the object is not in open state.
1

The Exception thrown by close can usually just be ignored (well you can log it). That's pretty much the same as throwing an exception in a destructor in C++ - there's not much (usually nothing) you can do about it and trying to close it again is nonsensical. Cleanup throwing exceptions is usually bad design - you can implement cleanup code for the cleanup but that's a recursive problem, in the end you'll just have to except that you can't handle it.

2 Comments

So why does it throw checked exception? - I can't ignore it
Well an unchecked exception would be a really bad idea (that's against the informal contract of unchecked exceptions being programmer errors). So, no exception? Surely a possibility, but there are scenarios where you want to handle such an exception (and let it be just log it). But just because it throws an exception doesn't mean you can't use an empty catch block to ignore it..

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.