Skip to content

Commit 7d4ecc5

Browse files
Added request and response processors that ensures they are not null (#265)
1 parent f93f973 commit 7d4ecc5

20 files changed

+76
-13
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Threading;
4+
using System.Threading.Tasks;
5+
6+
namespace OmniSharp.Extensions.JsonRpc.Pipelines
7+
{
8+
public class RequestMustNotBeNullProcessor<T> : MediatR.Pipeline.IRequestPreProcessor<T>
9+
{
10+
public Task Process(T request, CancellationToken cancellationToken)
11+
{
12+
if (typeof(T).IsClass && EqualityComparer<T>.Default.Equals(request, default))
13+
throw new ArgumentNullException(nameof(request), $"Pipeline request ({typeof(T).FullName}) must not be null");
14+
return Task.CompletedTask;
15+
}
16+
}
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Threading;
4+
using System.Threading.Tasks;
5+
6+
namespace OmniSharp.Extensions.JsonRpc.Pipelines
7+
{
8+
public class ResponseMustNotBeNullProcessor<T, R> : MediatR.Pipeline.IRequestPostProcessor<T, R>
9+
{
10+
public Task Process(T request, R response, CancellationToken cancellationToken)
11+
{
12+
if (typeof(R).IsClass && EqualityComparer<R>.Default.Equals(response, default))
13+
throw new ArgumentNullException(nameof(request), $"Pipeline response ({typeof(R).FullName}) must not be null");
14+
return Task.CompletedTask;
15+
}
16+
}
17+
}

src/JsonRpc/ServiceCollectionExtensions.cs

+6-5
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22
using System.Collections.Generic;
33
using System.Reflection;
44
using MediatR;
5+
using MediatR.Pipeline;
56
using MediatR.Registration;
67
using Microsoft.Extensions.DependencyInjection;
78
using Microsoft.Extensions.DependencyInjection.Extensions;
9+
using OmniSharp.Extensions.JsonRpc.Pipelines;
810

911
namespace OmniSharp.Extensions.JsonRpc
1012
{
@@ -14,13 +16,11 @@ public static IServiceCollection AddJsonRpcMediatR(this IServiceCollection servi
1416
{
1517
ServiceRegistrar.AddRequiredServices(services, new MediatRServiceConfiguration());
1618
ServiceRegistrar.AddMediatRClasses(services, assemblies);
19+
services.AddTransient(typeof(IRequestPreProcessor<>), typeof(RequestMustNotBeNullProcessor<>));
20+
services.AddTransient(typeof(IRequestPostProcessor<,>), typeof(ResponseMustNotBeNullProcessor<,>));
1721
services.AddScoped<IRequestContext, RequestContext>();
1822
services.RemoveAll<ServiceFactory>();
19-
services.AddScoped<ServiceFactory>(
20-
serviceProvider => {
21-
return serviceType => GetHandler(serviceProvider, serviceType);
22-
}
23-
);
23+
services.AddScoped<ServiceFactory>(serviceProvider => { return serviceType => GetHandler(serviceProvider, serviceType); });
2424
return services;
2525
}
2626

@@ -32,6 +32,7 @@ private static object GetHandler(IServiceProvider serviceProvider, Type serviceT
3232
var context = serviceProvider.GetService<IRequestContext>();
3333
return context.Descriptor != null ? context.Descriptor.Handler : serviceProvider.GetService(serviceType);
3434
}
35+
3536
return serviceProvider.GetService(serviceType);
3637
}
3738
}

test/JsonRpc.Tests/IntegrationTests.cs

+36
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Threading;
55
using System.Threading.Tasks;
66
using FluentAssertions;
7+
using MediatR;
78
using OmniSharp.Extensions.JsonRpc;
89
using OmniSharp.Extensions.JsonRpc.Server;
910
using OmniSharp.Extensions.JsonRpc.Testing;
@@ -17,6 +18,11 @@ public IntegrationTests() : base(new JsonRpcTestOptions())
1718
{
1819
}
1920

21+
class Request : IRequest<Data>
22+
{
23+
24+
}
25+
2026
class Data
2127
{
2228
public string Value { get; set; }
@@ -37,6 +43,36 @@ public async Task Should_Send_and_receive_requests()
3743
clientResponse.Value.Should().Be("myresponse");
3844
}
3945

46+
[Fact]
47+
public async Task Should_throw_when_sending_requests()
48+
{
49+
var (client, server) = await Initialize(
50+
client => { client.OnRequest("myrequest", async (Request request) => new Data() {Value = "myresponse"}); },
51+
server => { server.OnRequest("myrequest", async (Request request) => new Data() {Value = string.Join("", "myresponse".Reverse())}); }
52+
);
53+
54+
Func<Task> clientRequest = () => client.SendRequest("myrequest", (Request)null).Returning<Data>(CancellationToken);
55+
clientRequest.Should().Throw<InvalidParametersException>();
56+
57+
Func<Task> serverRequest = () => server.SendRequest("myrequest", (Request)null).Returning<Data>(CancellationToken);
58+
serverRequest.Should().Throw<InvalidParametersException>();
59+
}
60+
61+
[Fact]
62+
public async Task Should_throw_when_receiving_requests()
63+
{
64+
var (client, server) = await Initialize(
65+
client => { client.OnRequest("myrequest", async (Request request) => (Data)null); },
66+
server => { server.OnRequest("myrequest", async (Request request) => (Data)null); }
67+
);
68+
69+
Func<Task> clientRequest = () => client.SendRequest("myrequest", new Request()).Returning<Data>(CancellationToken);
70+
clientRequest.Should().Throw<InternalErrorException>();
71+
72+
Func<Task> serverRequest = () => server.SendRequest("myrequest", new Request()).Returning<Data>(CancellationToken);
73+
serverRequest.Should().Throw<InternalErrorException>();
74+
}
75+
4076
[Fact]
4177
public async Task Should_Send_and_receive_notifications()
4278
{

test/coverage/Client-Tests/coverage.netcoreapp2.1.info

Whitespace-only changes.

test/coverage/Client-Tests/coverage.netcoreapp2.1.json

-1
This file was deleted.

test/coverage/Client-Tests/coverage.netcoreapp3.1.info

Whitespace-only changes.

test/coverage/Client-Tests/coverage.netcoreapp3.1.json

-1
This file was deleted.

test/coverage/Dap-Tests/coverage.netcoreapp2.1.info

Whitespace-only changes.

test/coverage/Dap-Tests/coverage.netcoreapp2.1.json

-1
This file was deleted.

test/coverage/Dap-Tests/coverage.netcoreapp3.1.info

Whitespace-only changes.

test/coverage/Dap-Tests/coverage.netcoreapp3.1.json

-1
This file was deleted.

test/coverage/Generation-Tests/coverage.netcoreapp2.1.info

Whitespace-only changes.

test/coverage/Generation-Tests/coverage.netcoreapp2.1.json

-1
This file was deleted.

test/coverage/Generation-Tests/coverage.netcoreapp3.1.info

Whitespace-only changes.

test/coverage/Generation-Tests/coverage.netcoreapp3.1.json

-1
This file was deleted.

test/coverage/JsonRpc-Tests/coverage.netcoreapp2.1.info

Whitespace-only changes.

test/coverage/JsonRpc-Tests/coverage.netcoreapp2.1.json

-1
This file was deleted.

test/coverage/JsonRpc-Tests/coverage.netcoreapp3.1.info

Whitespace-only changes.

test/coverage/JsonRpc-Tests/coverage.netcoreapp3.1.json

-1
This file was deleted.

0 commit comments

Comments
 (0)