Search code examples
javaruntimeexception

In java, is it bad practice to use Runtime Exception as a super "break" through function calls?


Sometimes, there is a series of function calls, where at middle you determined the result and you want to stop the whole function chain middle way. In such case, is the following way bad?

public ResponseObject composeResponse {
   try {
       ResponseObject response = new ResponseObject();
       processA(response);
       processB(response);
       processC(response);
       processD(response);
          .
          .
          .
       return response;
       } catch (SomeFlagException e){
       return response;        
       }
   }

where for each process function, it is also like

public void processA(ResponseObject response){
    minorProcess1(response);
    minorProcess2(response);
    minorProcess3(response);
      .
      .
      .
}

In some particular conditions, say minorProcess3(), have such case that the result is determined and the rest of the processes are not wanted. Assume this happens in lot of the minorProcesses.

public void minorProcess3(ResponseObject response){
    //some process
    if (someFlag){
        //want end the process and return the result
        throw new SomeFlagException(); //SomeFlagException extends RuntimeException
    }
}

My mind is telling me no, for it is not an "exception" but an expectable outcome. And I heard that unchecked Exception should only be throwed when it cannot be reasonably resolved. But I could only think out this way to make code clean, otherwise the code will have to cascade the conditions check all the way back to the base function.

EDIT: Adding info on my situation. It is a web project, so it suppose to return proper response with payload. Sometimes the request should be responded by a 204/40x. No payload required, and therefore further process is not necessary and should be abandoned.


Solution

  • Yes, doing so is really bad practice.

    An exception means that some method could not fulfill its contract. The approach you ask about turns this to the opposite: use an exception to mean early success.

    Although it will technically work, it's so much against the intended meaning of exceptions that I have to strongly recommend against using such an approach.

    And I heard that unchecked Exception should only be throwed when it cannot be reasonably resolved.

    IMHO, this is bad advice. As the one throwing an exception, how can you know if some caller method up the call stack can continue successfully after your failure? That's only decidable in the context of the caller (whether it has a fallback strategy for the failure or not), and rarely depends on the type of exception. It's not your responsibility to decide that, and even if you tried to make that decision, it would most probably turn out wrong.

    E.g. for your caller, it typically doesn't matter if you failed because of NullPointerException or IOException, just to name two prominent examples of the unchecked / checked categories. What matters, is that you failed, and maybe the caller knows how to proceed after your failure.