Is it better practice to have void method throw an exception or to have the method return a boolean?

  • This falls straight into the same category with the recent "Is it better practice to return if false or execute an if statement if true?" question.



    Often, while writing code, I find myself presented with two options. Either I can do this:



    public void myMethod() throws Exception {
    // Some code
    validate(some_object_or_condition);
    // Some code
    }

    private void validate(Object arg) throws Exception {
    // Code that validates the argument and throws an exception if it's invalid
    }


    Or this:



    public void myMethod() throws Exception {
    // Some code
    if( !isValid(some_object_or_condition) ) throw new Exception();
    // Some code
    }

    private boolean isValid(Object arg) {
    // Code that returns a boolean based on whether or not the argument is valid
    }


    Is either one preferable over the other? When I was still just learning Java the latter felt more "object oriented" and somehow more natural. However, with experience the former has started to feel better because then the code looks cleaner to me, but I'm afraid people might find it less readable.



    Edit/Add: This time I ran into this problem when implementing a game (just for the fun of it) where the user would place words into a grid. The playWord method may fail because of the word not actually being a real word (yielding an InvalidWordException) or because the user is trying to place a valid word into an illegal position (yielding a WordPlacementException). If the method does not fail, it should return the score of the word as an integer. So in my case the playWord method first calls the method that validates the word and later the method that validates the location of the word, and these provoked this question here.


  • dreza

    dreza Correct answer

    9 years ago

    There's quite a few questions about this on stackoverflow but I think my general rule tends to be leave exceptions for exceptional circumstances and booleans for where failure occurances is an accepted/known possible behaviour.



    So I personally probably prefer your option 2 (interested to see what others think), where if anything the exception is thrown a bit higher up the chain. That way I could re-use the isValid logic elsewhere and deal with the failure without needing to wrap it in an exception handler.



    Of course, I think this is probably a case by case basis and depends on the kind of logic being checked.



    I'm sure I remember a really good Q&A on this somewhere but can't quite find it. However found a couple of discussions:



    Throw exception or return boolean - SO



    Throwing exceptions - SO



    EDIT: To further comment after the edits, perhaps you could also consider the option of returning status codes (enums) instead of the exceptions if there are a number of options. This has the benefit of being more efficient however as some have mentioned on SO could expose unecessary workings if this is a API or assembly. Some links I found on SO about this with some good discussions were:



    Exception or error code enum
    to use error codes or not



    And there were more. I see this coming down to a few options.




    1. Throw exception

    2. Return true/false

    3. Return a status/error code enum



    All probably have their place. Exceptions do occur the most overhead so if performance is an issue or the routine is called in many places perhaps this is not the best solution. I also saw mention that it was not necessarily a good idea to use exceptions to control the flow of application logic which it would seem to be doing in your case?



    Basically my thoughts are to use return true/false, use a status error code, and then exceptions in that order.



    An alternative suggestion might be something along the lines of (whether it's a decent alternative or not hopefully someone might comment on ???):



    public int playWord(string w) {
    Word word = new Word(word);
    if (word.isValid()) {
    return word.getScore();
    } else {
    throw new InvalidDataException(word.GetErrorMessage());
    }
    }

    class Word {
    private String word;
    private String errorMessage = null;

    public Word(string w) {
    word = w;
    }

    public boolean IsValid() {
    // TODO: perform various checks calling private methods as required and if fail store against errorMessage
    return errorMessage == null;
    }

    public String GetErrorMessage() {
    return errorMessage;
    }

    public int getScore(string word) {
    // return the score of the word no matter what it is
    }
    }

    Hey, thanks for the links. I indeed didn't take a look at SO before posting this because SO is not generally very welcoming for these kinds of questions where a definite answer may not exist and where there's no broken code. The problem with leaving exceptions for exceptional circumstances is how to define when a circumstance is exceptional enough. I've edited my post to contain a practical example (or two, if you want to read it that way), could you please take a look at it again?

License under CC-BY-SA with attribution


Content dated before 7/24/2021 11:53 AM