My snippet:
class Program
{
public class Args
{
[Option('n', "name", Required = true)]
public string Name { get; set; }
}
static void Main(string[] args)
{
Args parsedArgs;
Parser.Default.ParseArguments<Args>(args).WithParsed(result => parsedArgs = result).WithNotParsed(ThrowOnParseError);
}
private static void ThrowOnParseError(IEnumerable<Error> errors)
{
var excList = new List<Exception>();
foreach (var err in errors)
{
excList.Add(new ArgumentException(err.ToString()));
}
if (excList.Any())
throw new AggregateException(excList);
}
}
I would like to throw errors as ArgumentException with message being the same message that gets printed when error occurs. For example, when option -n is missing, this text is printed:
CmdLineParserTest 1.0.0.0
Copyright c 2019ERROR(S):
Required option 'n, name' is missing.-n, --name Required.
--help Display this help screen.
--version Display version information.
I would like to throw ArgumentException with "Required option 'n, name' is missing." being its message.
I looked into HelpText, but im not sure if it's what i need.
New guy here who is trying out library for first time! I also wanted to do the same thing. :)
err.Tag is an ErrorType Flags enum.
You can do the following to find out if an error flag is set:
if(err.Tag.HasFlag(ErrorType.BadVerbSelectedError))
//Do something for that type of error here
Unfortunately, it looks like you will have to enumerate every single possible ErrorType to handle all cases.
Also, it doesn't let you get the exact error details. Only the error type. The library seems a bit lacking in this regard. Seems weird to have an Errors collection and not have more details in them.
Damn, it was really harder than it should have been.
Turns out HelpText was the way to go, but it's so obscure.
Had to do this:
public class Args
{
[Option('n', "name", Required = true)]
public string Name { get; set; }
}
static void Main(string[] args)
{
Args parsedArgs;
var parseResult = Parser.Default.ParseArguments<Args>(args);
parseResult.WithParsed(result => Console.WriteLine(result.Name));
parseResult.WithNotParsed(errs => ThrowOnParseError(parseResult, errs));
}
private static void ThrowOnParseError<T>(ParserResult<T> result, IEnumerable<Error> errors)
{
var builder = SentenceBuilder.Create();
var errorMessages = HelpText.RenderParsingErrorsTextAsLines(result, builder.FormatError, builder.FormatMutuallyExclusiveSetErrors, 1);
var excList = errorMessages.Select(msg => new ArgumentException(msg)).ToList();
if (excList.Any())
throw new AggregateException(excList);
}
Nice approach that also worked for me, but I noticed that the error list is actually not needed inside the static method. Also, I think that an extension method would be cleaner in this case:
public static ParserResult<T> ThrowOnParseError<T>(this ParserResult<T> result)
{
if (!(result is NotParsed<T>))
{
// Case with no errors needs to be detected explicitly, otherwise the .Select line will throw an InvalidCastException
return result;
}
var builder = SentenceBuilder.Create();
var errorMessages = HelpText.RenderParsingErrorsTextAsLines(result, builder.FormatError, builder.FormatMutuallyExclusiveSetErrors, 1);
var excList = errorMessages.Select(msg => new ArgumentException(msg)).ToList();
if (excList.Any())
{
throw new AggregateException(excList);
}
return result;
}
That way, you can keep using the fluent API:
Parser.Default.ParseArguments<Args>(args)
.WithParsed(result => Console.WriteLine(result.Name))
.ThrowOnParseError()
.Etc()
The [Pr #634) exposes the Errors to the base class, available in develop branch and will be released in v2.9.
You can:
var result = Parser.Default.ParseArguments<Options>(args);
var errors= result.Errors;
Most helpful comment
Damn, it was really harder than it should have been.
Turns out HelpText was the way to go, but it's so obscure.
Had to do this: