On 22-05-2010 15:05, Rhino wrote:
Catch the exception but display something else that the exception text.
Exceptions texts are for log files to be handed over to developers.
For user input I don't even think that you should throw an exception.
Maybe just test and tell the user to correct.
Bad user input is not really exceptional enough to justify an exception..
I disagree. We've had arguments about the proper use of exceptions on this
newsgroup before, so i recognise that this is a matter where opinions
vary, but exceptions seem like a perfectly acceptable option for dealing
with bad user input to me. They might not be the right solution in every
situation, but they are an option that can be considered.
Of course, i wouldn't show the exception's error message to the user. An
approach i've seen is to do something like:
public class ValidationException extends Exception {
private final String validationKey;
private final Object[] parameters;
public ValidationException(String validationKey, Object.. parameters) {
super(format(validationKey, Locale.getDefault()));
this.validationKey = validationKey;
this.parameters = parameters;
}
public String format(Locale locale) {
return format(validationKey, locale);
}
private static String format(String validationKey, Locale locale) {
ResourceBundle bundle = ResourceBundle.getBundle("ValidationMessages", locale);
String pattern = bundle.getString(validationKey);
MessageFormat fmt = new MessageFormat(pattern, locale);
return fmt.format(parameters);
}
}
ValidationExceptions have a message in the language of the default locale
(or you could hardcode this to english if you wanted), which can be used
in logging and so on, but can also supply their message in other
languages, as needed.
If you put on a getter for the fields, then code that handles them can
also act on the key and parameters in other ways, as appropriate, if
simply printing the messasge is not adequate. Although in this case, you
should probably be using subclasses rather than switching on the contents
of the key. If you do subclass, you can refine the above approach by
pushing the parameters down into subclasses, accessed via an abstract
getParameters method in the base class. That lets you construct the array
on the fly from meaningful fields:
public class AgeTooYoungException extends ValidationException {
private final int actualAge;
private final int requiredAge;
// constructor
protected Object[] getParameters() {
return new Object[] {actualAge, requiredAge};
}
// getters
}
Code which catches this and is interested in the ages can then discover
them via proper getter calls, rather than having to scrub about in an
untyped parameter array.
Another refinement is to add a field which somehow indicates which bit of
user input was wrong - a simple string key might be enough. The UI code
can then attach the error message to the right bit of the UI simply by
matching that up.