From 6f74e24e57510260535ec72ff69910c0a6289ccc Mon Sep 17 00:00:00 2001 From: Joe4evr Date: Sat, 18 Aug 2018 09:59:20 +0200 Subject: [PATCH] Add a catch to wrap parsing/input errors --- .../Readers/NamedArgumentTypeReader.cs | 26 +++++++++++++------ test/Discord.Net.Tests/Tests.TypeReaders.cs | 22 ++++++++++++++++ 2 files changed, 40 insertions(+), 8 deletions(-) diff --git a/src/Discord.Net.Commands/Readers/NamedArgumentTypeReader.cs b/src/Discord.Net.Commands/Readers/NamedArgumentTypeReader.cs index 9b7eef5a7..c3f54cffa 100644 --- a/src/Discord.Net.Commands/Readers/NamedArgumentTypeReader.cs +++ b/src/Discord.Net.Commands/Readers/NamedArgumentTypeReader.cs @@ -10,8 +10,7 @@ namespace Discord.Commands internal sealed class NamedArgumentTypeReader : TypeReader where T : class, new() { - private static readonly TypeInfo _tInfo = typeof(T).GetTypeInfo(); - private static readonly IReadOnlyDictionary _tProps = _tInfo.DeclaredProperties + private static readonly IReadOnlyDictionary _tProps = typeof(T).GetTypeInfo().DeclaredProperties .Where(p => p.SetMethod != null && p.SetMethod.IsPublic && !p.SetMethod.IsStatic) .ToImmutableDictionary(p => p.Name, StringComparer.OrdinalIgnoreCase); @@ -30,12 +29,20 @@ namespace Discord.Commands while (state != ReadState.End) { - var prop = Read(out var arg); - var propVal = await ReadArgumentAsync(prop, arg).ConfigureAwait(false); - if (propVal != null) - prop.SetMethod.Invoke(result, new[] { propVal }); - else - return TypeReaderResult.FromError(CommandError.ParseFailed, $"Could not parse the argument for the parameter '{prop.Name}' as type '{prop.PropertyType}'."); + try + { + var prop = Read(out var arg); + var propVal = await ReadArgumentAsync(prop, arg).ConfigureAwait(false); + if (propVal != null) + prop.SetMethod.Invoke(result, new[] { propVal }); + else + return TypeReaderResult.FromError(CommandError.ParseFailed, $"Could not parse the argument for the parameter '{prop.Name}' as type '{prop.PropertyType}'."); + } + catch (Exception ex) + { + //TODO: use the Exception overload after a rebase on latest + return TypeReaderResult.FromError(CommandError.Exception, ex.Message); + } } return TypeReaderResult.FromSuccess(result); @@ -92,6 +99,9 @@ namespace Discord.Commands } } + if (currentParam == null) + throw new InvalidOperationException("No parameter name was read."); + return GetPropAndValue(out arg); PropertyInfo GetPropAndValue(out string argv) diff --git a/test/Discord.Net.Tests/Tests.TypeReaders.cs b/test/Discord.Net.Tests/Tests.TypeReaders.cs index f2ddf9cb3..884f8d511 100644 --- a/test/Discord.Net.Tests/Tests.TypeReaders.cs +++ b/test/Discord.Net.Tests/Tests.TypeReaders.cs @@ -58,6 +58,28 @@ namespace Discord Assert.Equal(expected: 42, actual: m.Foo); Assert.Equal(expected: "hello", actual: m.Bar); } + + [Fact] + public async Task TestNonPatternInput() + { + var commands = new CommandService(); + var module = await commands.AddModuleAsync(null); + + Assert.NotNull(module); + Assert.NotEmpty(module.Commands); + + var cmd = module.Commands[0]; + Assert.NotNull(cmd); + Assert.NotEmpty(cmd.Parameters); + + var param = cmd.Parameters[0]; + Assert.NotNull(param); + Assert.True(param.IsRemainder); + + var result = await param.ParseAsync(null, "foobar"); + Assert.False(result.IsSuccess); + Assert.Equal(expected: CommandError.Exception, actual: result.Error); + } } [NamedArgumentType]