zaharpopov
zaharpopov

Reputation: 17272

nested IOException catch for socket close

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

Upvotes: 3

Views: 5515

Answers (2)

gpeche
gpeche

Reputation: 22514

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.

Upvotes: 5

Voo
Voo

Reputation: 30216

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.

Upvotes: 1

Related Questions