1

I am trying to learn trough example on a proper way to handle exceptions. When should I catch it, when and how should I throw it further down the line ?

In this example I have a very simple setup:

  • MainMethod
    • ExceptionHandler // Here is where I'd like to catch and resolve most exceptions
      • ExceptionGenerator // Errors start from here

public List<String> readFile(String pathStr) throws InvalidPathException, IOException {

    Path path = Paths.get(Repository.fixPath(pathStr));         // This can throw both FileNotFoundException and InvalidPathException, I think. It should!
    List<String> fileContent;

    try {

        fileContent = Files.readAllLines(path, StandardCharsets.UTF_8);
        return fileContent;

    } catch (IOException e) {
        throw new IOException("Could not read file content");
    }
}


// FileNotFoundException (FNFE) should be sent to the previous method
private static String fixPath(String path) throws FileNotFoundException {

    if (path.isEmpty() || path == null) 
        throw new FileNotFoundException();

    ...

    return path;
}

Points of interest:

  • Should my readFiles method catch the FileNotFoundException thrown by the second method ? Should I then throw it again, like with the IOException ? How does the message exactly work (the parameter for the exception)? Is it actually usable in any way except printing it out ?

  • If I have IOException (it supersedes the FNFE, can I still throw the FNFE then just catch FNFE first, and IOE second?)

  • 1
    There isn't a unified answer for "where and when should I catch the exception", as it comes from the functionality of your code. If you want the user of your app know, that something's gone wrong, you catch the exception in presentation layer and show the user an error, if you throw an exception, but its state does not need to be shown to the user, because it is mostly there for debugging purpose and wouldn't affect the flow of your program, catch and handle it in a function which uses a function throwing the exception and don't show it to the end user. – Andy Sep 15 '15 at 10:11
2
catch (IOException e) {
    throw new IOException("Could not read file content");
}

This is a very bad practise because you are losing all the stacktrace of e ! Therefore when catching this exception you won't have any information of the root cause of the exception.

If you really need to add a specific message at this layer, consider doing it like this: throw new IOException("Could not read file content", e);


What readFile must throw ? It depends on the verbosity you want to expose.

Verbose case

public List<String> readFile(String pathStr) throws FileNotFoundException, IOException { }

This case is appropriate when you want to indicate to the caller that the exceptions throwed by this method should be handled differently.

Less verbose case

public List<String> readFile(String pathStr) throws IOException { }

This case is appropriate when you don't want to bother with the details of the exception (just knowing "something went wrong" is enough).

  • The reason I would not like just the supertype is because not finding the file and not being able to read its contents would be handled in different ways. – Kalec Sep 15 '15 at 10:04
  • Also, if the second method throws an exception in the first method that also throws that type of exceptions, does it propagate it even if not explicitly told to? – Kalec Sep 15 '15 at 10:06
  • 1
    @Kalec If both methods signatures throw the same type of exception, the exception will propagate automatically (aka bubble-up). – Spotted Sep 15 '15 at 10:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.