It's hard to find a consensus, although many people say you should not use exceptions to handle bad user input. Still, I'm not convinced that it's the bad thing to do in my specific case. Could you try to explain why I'm wrong?
My code (please focus just on the exception handling aspect) follows. My rational for using exceptions here is that if I didn't, assuming I would want to keep the validation logic close to the keyword parsing (because parsing and validation are tightly coupled), I would have to change three methods (submitOnAdd, submitOnUpdate, getKeywords) to make them handle this exceptional situation. Do you think I definitely wrong in this case to use exceptions, or is it a matter of personal style?
public SubmitResponse internalSubmit(Map<String, String[]> submitParameters) {
try {
if (!submitParameters.containsKey("foo")) {
return submitOnAdd(submitParameters);
} else {
return submitOnModify(submitParameters);
}
} catch (SubmitErrorException e) {
return SubmitResponse.fieldError(Arrays.asList(e.getSubmitError()));
}
}
SubmitResponse submitOnAdd(Map<String, String[]> submitParamters) {
// do some stuff
// ...
if (addKeywordList(createKeywordList(submitParameters.get("concatenated_keywords"))
return SubmitResponse.OK();
return SubmitResponse.bad("Failed to add");
}
SubmitResponse submitOnUpdate(Map<String, String[]> submitParamters) {
// do some other stuff
// ...
if (updateKeywordList(createKeywordList(submitParameters.get("concatenated_keywords"))
return SubmitResponse.OK();
return SubmitResponse.bad("Failed to update");
}
List<Keyword> getKeywords(String concatenatedKeywords) {
List<String> rawKeywords = splitKeywords(concatenatedKeywords);
return Collections.transform(new Function<String, Keyword>() {
@Override
public KeywordListProto.Keyword apply(String expression) {
return buildKeyword(expression);
}
});
}
private Keyword buildKeyword(String rawKeyword) {
// parse the raw keyword
if (/*parsing failed */)
throw new SubmitResponseException("Failed to parse keyword " + rawKeyword);
return parsedKeyword;
}