Browse Source

Add a catch to wrap parsing/input errors

pull/1123/head
Joe4evr 7 years ago
parent
commit
6f74e24e57
2 changed files with 40 additions and 8 deletions
  1. +18
    -8
      src/Discord.Net.Commands/Readers/NamedArgumentTypeReader.cs
  2. +22
    -0
      test/Discord.Net.Tests/Tests.TypeReaders.cs

+ 18
- 8
src/Discord.Net.Commands/Readers/NamedArgumentTypeReader.cs View File

@@ -10,8 +10,7 @@ namespace Discord.Commands
internal sealed class NamedArgumentTypeReader<T> : TypeReader internal sealed class NamedArgumentTypeReader<T> : TypeReader
where T : class, new() where T : class, new()
{ {
private static readonly TypeInfo _tInfo = typeof(T).GetTypeInfo();
private static readonly IReadOnlyDictionary<string, PropertyInfo> _tProps = _tInfo.DeclaredProperties
private static readonly IReadOnlyDictionary<string, PropertyInfo> _tProps = typeof(T).GetTypeInfo().DeclaredProperties
.Where(p => p.SetMethod != null && p.SetMethod.IsPublic && !p.SetMethod.IsStatic) .Where(p => p.SetMethod != null && p.SetMethod.IsPublic && !p.SetMethod.IsStatic)
.ToImmutableDictionary(p => p.Name, StringComparer.OrdinalIgnoreCase); .ToImmutableDictionary(p => p.Name, StringComparer.OrdinalIgnoreCase);


@@ -30,12 +29,20 @@ namespace Discord.Commands


while (state != ReadState.End) 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); 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); return GetPropAndValue(out arg);


PropertyInfo GetPropAndValue(out string argv) PropertyInfo GetPropAndValue(out string argv)


+ 22
- 0
test/Discord.Net.Tests/Tests.TypeReaders.cs View File

@@ -58,6 +58,28 @@ namespace Discord
Assert.Equal(expected: 42, actual: m.Foo); Assert.Equal(expected: 42, actual: m.Foo);
Assert.Equal(expected: "hello", actual: m.Bar); Assert.Equal(expected: "hello", actual: m.Bar);
} }

[Fact]
public async Task TestNonPatternInput()
{
var commands = new CommandService();
var module = await commands.AddModuleAsync<TestModule>(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] [NamedArgumentType]


Loading…
Cancel
Save