According to this link, if the source has a problem when opening and throws an exception and it is also in try parentheses, JVM closes it. My question is how to inform the user now that this source is closed and we encountered a problem when opening this resource? In other words, how can this exception be handled?
CodePudding user response:
Even when using a try-with-resources
, the catch
clause still works.
private static void printFile() throws MyCustomException {
try(FileInputStream input = new FileInputStream("file.txt")) {
int data = input.read();
while(data != -1){
System.out.print((char) data);
data = input.read();
}
} catch (IOException e) {
throw new MyCustomException("There was an error while opening the resource", e);
}
}
CodePudding user response:
Seems trivial. Usually, java code is running in some sort of 'no user interaction' environment (servers and the like). The right move is to let the exception bubble up - you want the daily job that is halfway through reading through the database to open the related file to then send the logs to long term storage or whatever it is to completely abort and write a note in the log file. Usually for jobs like that, there's some atomary functionality (in this case, perhaps each such file is independent of the others, and its okay to leave the 'broken' one in place for now until a server admin can look at it whilst continuing to process the remainder - in that case, the 'do the backup rotation thing on THIS file' is the atomary functionality): Catch all exceptions and write code that does what you want when the job fails. For example, my servers can send notifications straight to admin phones (via telegram or pushover, or using slack API, and there are many services that automate this for you too), if it's important, you'd write that in your catch block.
For code that is directly 'triggered' by a user, let's say a 'save file' function, then it's not so much 'the resource is now closed' - resources are not long lived (they cannot be - not if you use try-with-resources). They were either never open in the first place (you attempt to save a file to a dir that doesn't exist - the act of trying to make the new OutputStream already failed, it was never open to begin with), or, perhaps it did open, but it was to a USB stick and the user pulled it out halfway through saving. The resource is just closed, effectively, whether in java you .close()
it or not - the entire stick is gone!!
The only thing the 'safe close' aspect of try-with-resources did for you is ensure that your Java Process isn't wasting a file handle.
You handle it the same way you handle pretty much any 'unrecoverable' (you can't write software that hypnotises the user into sticking that USB stick back into the machine, obviously - it is not recoverable as a consequence, like most exceptions) problem: You toss up a dialog box that explains the situation.
try {
try (OutputStream out = Files.newOutputStream(saveGameFile)) {
boardState.save(out);
}
} catch (IOException e) {
// show dialog here
}