Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exception not caught with dynamic #92

Closed
waynebrantley opened this issue May 11, 2017 · 3 comments
Closed

Exception not caught with dynamic #92

waynebrantley opened this issue May 11, 2017 · 3 comments
Assignees

Comments

@waynebrantley
Copy link

The first test passes.
The second test fails at the Assert.Throws line saying the exception was null.
(Look carefully, the only difference in the code is the use of the dynamic keyword.

[Test]
public void ExceptionIsThrownTaskValidator()
{
    var cmd = new ValidatorAsyncTaskCommand();
    var command = NunitSetup.ValidatorContainer.Resolve<IAsyncCommandHandler<ValidatorAsyncTaskCommand>>();
    Assert.Throws<FluentValidationException>(() => AsyncContext.Run(() => command.HandleAsync(cmd)));
    Assert.That(cmd.HandleFired, Is.False);
}

[Test]
public void ExceptionIsThrownTaskValidatorDynamic()
{
    var cmd = new ValidatorAsyncTaskCommand();
    dynamic command = NunitSetup.ValidatorContainer.Resolve<IAsyncCommandHandler<ValidatorAsyncTaskCommand>>();
    Assert.Throws<FluentValidationException>(() => AsyncContext.Run(() => command.HandleAsync(cmd)));
    Assert.That(cmd.HandleFired, Is.False);
}

The HandleAsync call looks like this (their is a decorator in place throwing the exception):

public Task HandleAsync(ValidatorAsyncTaskCommand command)
{
    command.HandleFired = true;
    return Task.CompletedTask;
}

If the HandleAsync call uses Task<T> instead of `Task`` then it works as expected!!!

If the command handler returns Task<T> then everything works as expected, regardless of if dynamic type is used.

If the command handler returns Task then the exception is eaten up if a dynamic type is used.

Further complicating the scenario, is the use of CQRS and decorators with autofac. If there is not a decorator in place (so the resolve results in the exact handler, it works even with dynamic. If the resolve results in a decorator that throws (or the original handle throws) this it fails.

Obviously the dynamic cast is not necessary in this contrived example, but in my real scenario it is.

I am using version 3.01, but have tried it on 4.01. (We never upgraded to 4 because of the zombie like nature of the build dependency that 4.01 takes on. Looking forward to the 5 version that cleans all this up)

@StephenCleary StephenCleary self-assigned this May 11, 2017
@StephenCleary
Copy link
Owner

This is almost certainly not a bug in AsyncEx, but I'll take a look at it. Can you post a minimal repro? Does the decorator return a faulted task, or does it throw directly?

Regarding the versions, I went through pretty good lengths to avoid Microsoft.Bcl.Build in 3.x, but it turned out that caused a subtle bug (#13), so 4.x had to remove all that work and just use the build package everywhere (unfortunately). 5.x is currently in prerelease mainly because it's still missing a few types; what is there is quite stable.

@waynebrantley
Copy link
Author

I am going to create a repro so you can see this. Thanks for comments.

  • I dont really know anything about Bcl.Build other than it is a zombie virus package and infects everything, so I avoid it!

@StephenCleary
Copy link
Owner

Feel free to reopen if you have a repro.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants