Java Error Handling – Returning Boolean and Message from Value Checker Function

error handlingjava

I have a value checking function, something much like a credit card number checking function, that is passed in a string, and needs to check that the value is of the right format.

If it's the right format it needs to return true.

If it's not the right format it needs to return false, and also tell us what's wrong with the value.

The question is, what's the nicest way to achieve this?

Here's a few solutions:

1. Use integer/enum return codes to signify meanings:

String[] returnCodeLookup = 
[
"Value contains wrong number of characters, should contain 10 characters",
"Value should end with 1", 
"Value should be a multiple of 3"
]

private int valueChecker(String value)
{
    /*check value*/
    return returnCode;
}

rc = checkValue(valueToBeChecked);
if rc == 0
{
    /*continue as normal*/
}
else
{
    print("Invalid value format: ") + returnCodeLookup[rc];
}

I don't like this solution as it it requires implementation on the caller side of things.

2. Create a returnCode class

Class ReturnCode()
{
    private boolean success;
    private String message;

    public boolean getSuccess()
    {
        return this.success;
    }

    public String getMessage()
    {
        return this.message; 
    }
}

private ReturnCode valueChecker(String value)
{
    /*check value*/
    return returnCode;
}

rc = checkValue(valueToBeChecked);
if rc.getSuccess()
{
    /*continue as normal*/
}
else
{
    print("Invalid value format: ") + rc.getMessage();
}

This solution is tidy, but it seems like overkill/reinventing the wheel.

3. Use exceptions.

private boolean valueChecker(String value)
{
    if int(value)%3 != 0 throw InvalidFormatException("Value should be a multiple of 3";
    /*etc*/
    return True;
}

try {
rc = checkValue(valueToBeChecked);
}

catch (InvalidFormatException e)
{
     print e.toString();
}

I'm tempted to use this solution, but I'm told that you shouldn't use exceptions for business logic.

Best Answer

Use a more complex return object that encapsulates both concerns. Example:

public interface IValidationResult {
  boolean isSuccess();
  String getMessage();
}

This has several advantages:

  1. Returns multiple related pieces of data in one object.
  2. Room for expansion if you need to add additional data in the future.
  3. No reliance on temporal coupling: you can validate multiple inputs and they do not clobber the message as in the other answer. You can check messages in any order, across threads even.

I have actually used this specific design before, in applications where a validation may be more than simply true or false. Perhaps a detailed message is necessary, or only part of the input is invalid (e.g. a form with ten elements might only have one or two invalid fields). Using this design, you can easily accommodate those requirements.

Related Topic