-1

The exact Error is: "There is a more general exception, 'java.lang.exception' in the throws list already"

I have a method like so:

public String myMethod() throws FileNotFoundException, IOException, Exception {
        try{  
            // DO STUFF

        }catch(FileNotFoundException e){
            // DO STUFF  
          throw new FileNotFoundException("custom message", e);

        }catch(IOException e){
          // DO STUFF
          throw new IOException("custom message", e); 

        }catch(Exception e){
          throw new Exception("custom message", e); 
        }
        return myString;
}

Intellij tells me that the first two are redundant because I have the more general Exception at the end, is that the case?
Will the method throw an Exception even if I explicitly throw an IOException?
Or is it the case that generic Exceptions will be thrown up the stack anyway, so I don't even need Exception on the end ?

mal
  • 3,022
  • 5
  • 32
  • 62
  • your question makes no sense. This is the first-come, first-served principle. Only one Exception can be throwed at the time. No, the new Exception("", e) will not be thrown if you have an IOException, it will be if you don't catch IOException specifically and your code throws one – Stultuske Sep 06 '19 at 05:48
  • "they're not always reliable"?? what do you mean by that? They are quite reliable, do you really think an IDE could grow out to be one of the most used in a professional environment (especially if you have to pay to get all the functionalities) if it's not reliable? A better question here is: why do you use IntelliJ if you don't trust it to be reliable? – Stultuske Sep 06 '19 at 05:50
  • @Stultuske Yes I know that. But the linter says, as best I can tell, that because I have `Exception` in the `throws` part and that's more general than `IOException` then I should remove `IOException` from the `throws` at the top. But I don't want to have to check which type of exception it is further up the stack, I'd rather just throw the correct one from here.. – mal Sep 06 '19 at 05:51
  • @Stultuske not reliable is wrong, that was a bad phrase, I'll remove it. – mal Sep 06 '19 at 05:52
  • So the issue is that intellij prompts me to throw a more general exception when I don't want to. It's not always best to declare a method throws only the most general case, when internally the actual exception thrown is more specific. It's not transparent to the caller if you do it that way. That's my issue with the linter in this case. – mal Sep 06 '19 at 07:23
  • @bot_bot Your question is a little confusing for future readers: it looks like there is no clear reason why you *catch* the specified exceptions and then *rethrow* them to the caller. – MC Emperor Sep 06 '19 at 09:43
  • Yes, I can see that. I suppose one use case is where the issue need to be handled immediately here, but there are other places up the stack that need it too. For example, I'd rather throw the exception up the stack to a message publisher that can notify other services of the issue instead of having a message publisher in every lower level class to handle such things. – mal Sep 06 '19 at 09:49

1 Answers1

5

IntelliJ does tell you that the second catch block is never reached. FileNotFoundException is a subtype of IOException, so if such exception occurs, then the first catch block is executed, since IOException matches the FileNotFoundException being thrown.

The catch blocks are always evaluated in the order in which they are declared. That means that if you swap the two catch blocks, it'll work.

Update

According to your comment, it is not the try-catch blocks IntelliJ notices you about, but the throws clause.

That is because for checked exceptions, Java forces you to declare them to be thrown in the method declaration. It is only necessary for the most general exception to be declared in the throws clause. The IDE is saying that because you declared Exception to be thrown, there is no need to also declare any subclass of Exception, since those cases are already covered by Exception.

However, the reasons you might still want to do that, is to provide more information to the caller. See this question and answer on Software Engineering StackExchange.

More information:


I strongly discourage you to catch a too general exception. It's often a code smell.

MC Emperor
  • 22,334
  • 15
  • 80
  • 130
  • My apologies, I wrote the example wrong, my code is correct. I've fixed it now. The linter says the following: "There is a more general exception, 'java.lang.exception' in the throws list already" And the `FileNotFoundException` and `IOException` at the top are grayed out. – mal Sep 06 '19 at 06:03
  • Thank you very much. I've just been testing myself, and It appears that if I throw and `IOException` in a method that throws `Exception` I can still catch an `IOException` without having to check what it is first. I'll take a look Software Engineering StackExchange. And yes, this was my concern when I asked this question. I'd rather throw/catch the specific exception where possible, and was wondering if I could catch an `IOException` if the method definition says `throws Exception` only. It appears I can. – mal Sep 06 '19 at 07:18
  • But the issue then is others cannot see that I specifically throw `IOException` without going into my code to look. – mal Sep 06 '19 at 07:18
  • @bot_bot That's where Javadoc kicks in: you should document *what* your method is supposed to do, what it expects and how it handles exceptions. – MC Emperor Sep 06 '19 at 09:41