OctopusDeploy / Halibut

| Public | A secure communication stack for .NET using JSON-RPC over SSL.
Other
12 stars 44 forks source link

Passing null for a Nullable<T> parameter fails with AmbiguousMatchException #603

Open khellang opened 6 months ago

khellang commented 6 months ago

Team

What happened?

When passing null to an asynchronous service method accepting a Nullable<T> parameter, Halibut will not consider it a match and fails with the following exception:

Halibut.Exceptions.AmbiguousMethodMatchHalibutClientException : Could not decide which candidate to call out of the following methods:
 - System.Threading.Tasks.Task`1[System.Int32] IncrementAsync(System.Threading.CancellationToken)
 - System.Threading.Tasks.Task`1[System.Int32] IncrementAsync(System.Nullable`1[System.Int32], System.Threading.CancellationToken)
The request arguments were:
<null>

Reproduction

Define an async service method like this:

    public interface ICountingService
    {
        public int Increment(int? number);
    }

    public interface IAsyncCountingService
    {
        public Task<int> IncrementAsync(int? number, CancellationToken cancellationToken);
    }

And invoke it like this:

[Test]
public async Task AsyncInvokeWithNullableParamsOnAsyncService()
{
    var serviceFactory = new ServiceFactoryBuilder()
        .WithConventionVerificationDisabled()
        .WithService<ICountingService, IAsyncCountingService>(() => new AsyncCountingService())
        .Build();

    var sut = new ServiceInvoker(serviceFactory);
    var request = new RequestMessage()
    {
        ServiceName = nameof(ICountingService),
        MethodName = nameof(ICountingService.Increment),
        Params = new object[] { null! },
    };

    var response = await sut.InvokeAsync(request);
    response.Result.Should().Be(1);
}

Error and Stacktrace

Halibut.Exceptions.AmbiguousMethodMatchHalibutClientException : Could not decide which candidate to call out of the following methods:
 - System.Threading.Tasks.Task`1[System.Int32] IncrementAsync(System.Threading.CancellationToken)
 - System.Threading.Tasks.Task`1[System.Int32] IncrementAsync(System.Nullable`1[System.Int32], System.Threading.CancellationToken)
The request arguments were:
<null>

More Information

I have written a test and patched the bug, will submit a PR ASAP.

Workaround

No response