diff --git a/src/main/java/io/airlift/airline/ParseOptionConversionException.java b/src/main/java/io/airlift/airline/ParseOptionConversionException.java index b83ab1cfe..34baabce1 100644 --- a/src/main/java/io/airlift/airline/ParseOptionConversionException.java +++ b/src/main/java/io/airlift/airline/ParseOptionConversionException.java @@ -24,14 +24,19 @@ public class ParseOptionConversionException extends ParseException private final String value; private final String typeName; - ParseOptionConversionException(String optionTitle, String value, String typeName) + ParseOptionConversionException(String optionTitle, String value, String typeName, String additionalComment) { - super("%s: can not convert \"%s\" to a %s", optionTitle, value, typeName); + super("%s: can not convert \"%s\" to a %s. %s", optionTitle, value, typeName, additionalComment); this.optionTitle = optionTitle; this.value = value; this.typeName = typeName; } + ParseOptionConversionException(String optionTitle, String value, String typeName) + { + this(optionTitle, value, typeName, ""); + } + public String getOptionTitle() { return optionTitle; diff --git a/src/main/java/io/airlift/airline/TypeConverter.java b/src/main/java/io/airlift/airline/TypeConverter.java index ae4543f40..9aadc9b81 100644 --- a/src/main/java/io/airlift/airline/TypeConverter.java +++ b/src/main/java/io/airlift/airline/TypeConverter.java @@ -1,9 +1,15 @@ package io.airlift.airline; +import com.google.common.base.Function; +import com.google.common.base.Joiner; import com.google.common.base.Preconditions; +import com.google.common.collect.Lists; import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.List; public class TypeConverter { @@ -53,16 +59,35 @@ else if (Double.class.isAssignableFrom(type) || Double.TYPE.isAssignableFrom(typ if (valueOf.getReturnType().isAssignableFrom(type)) { return valueOf.invoke(null, value); } - } catch (Throwable ignored) { + } + catch (Throwable ignored) { } // Look for a static valueOf(String) method (this covers enums which have a valueOf method) try { Method valueOf = type.getMethod("valueOf", String.class); if (valueOf.getReturnType().isAssignableFrom(type)) { - return valueOf.invoke(null, value); + try { + return valueOf.invoke(null, value); + } + catch (InvocationTargetException e) { + if (type.isEnum()) { + List enumConstantNames = Lists.transform(Arrays.asList(((Class) type).getEnumConstants()), new Function() { + @Override + public String apply(Enum input) + { + return input.name(); + } + }); + String message = String.format("Invalid %s, Valid values are: %s", name, Joiner.on(", ").join(enumConstantNames)); + throw new ParseOptionConversionException(name, value, type.getSimpleName(), message); + } + } } } + catch (ParseOptionConversionException e) { + throw e; + } catch (Throwable ignored) { }