-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #97 from wemogy/main
Release
- Loading branch information
Showing
21 changed files
with
421 additions
and
200 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
35 changes: 23 additions & 12 deletions
35
....CQRS.Extensions.FastEndpoints.TestWebApp/Commands/ThrowError/ThrowErrorCommandHandler.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,36 @@ | ||
using Wemogy.Core.Errors; | ||
using Wemogy.Core.Errors.Enums; | ||
using Wemogy.Core.Errors.Exceptions; | ||
using Wemogy.CQRS.Commands.Abstractions; | ||
|
||
namespace Wemogy.CQRS.Extensions.FastEndpoints.TestWebApp.Commands.ThrowError; | ||
|
||
public class ThrowErrorCommandHandler : ICommandHandler<ThrowErrorCommand> | ||
{ | ||
public Task HandleAsync(ThrowErrorCommand command) | ||
{ | ||
throw new CustomErrorException( | ||
command.ErrorType, | ||
"CustomError", | ||
"This is a custom error", | ||
null); | ||
} | ||
private const string DummyErrorCode = "DummyErrorCode"; | ||
private const string DummyErrorDescription = "DummyErrorDescription"; | ||
|
||
class CustomErrorException : ErrorException | ||
public Task HandleAsync(ThrowErrorCommand command) | ||
{ | ||
public CustomErrorException(ErrorType errorType, string code, string description, Exception? innerException) | ||
: base(errorType, code, description, innerException) | ||
switch (command.ErrorType) | ||
{ | ||
case ErrorType.Failure: | ||
throw Error.Failure(DummyErrorCode, DummyErrorDescription); | ||
case ErrorType.Unexpected: | ||
throw Error.Unexpected(DummyErrorCode, DummyErrorDescription); | ||
case ErrorType.Validation: | ||
throw Error.Validation(DummyErrorCode, DummyErrorDescription); | ||
case ErrorType.Conflict: | ||
throw Error.Conflict(DummyErrorCode, DummyErrorDescription); | ||
case ErrorType.NotFound: | ||
throw Error.NotFound(DummyErrorCode, DummyErrorDescription); | ||
case ErrorType.Authorization: | ||
throw Error.Authorization(DummyErrorCode, DummyErrorDescription); | ||
case ErrorType.PreconditionFailed: | ||
throw Error.PreconditionFailed(DummyErrorCode, DummyErrorDescription); | ||
} | ||
|
||
throw Error.Unexpected( | ||
"ErrorTypeNotSupported", | ||
$"The ErrorType {command.ErrorType} is not supported!"); | ||
} | ||
} |
46 changes: 46 additions & 0 deletions
46
...gy.CQRS.Extensions.FastEndpoints.UnitTests/Endpoints/CommandEndpointBaseExceptionTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
using FluentAssertions; | ||
using Microsoft.AspNetCore.Mvc.Testing; | ||
using Wemogy.Core.Errors.Enums; | ||
using Wemogy.Core.Errors.Exceptions; | ||
using Wemogy.CQRS.Commands.Abstractions; | ||
using Wemogy.CQRS.Extensions.FastEndpoints.TestWebApp.Commands.ThrowError; | ||
|
||
namespace Wemogy.CQRS.Extensions.FastEndpoints.UnitTests.Endpoints; | ||
|
||
public class CommandEndpointBaseExceptionTests : IClassFixture<WebApplicationFactory<Program>> | ||
{ | ||
private readonly WebApplicationFactory<Program> _factory; | ||
|
||
public CommandEndpointBaseExceptionTests(WebApplicationFactory<Program> factory) | ||
{ | ||
_factory = factory; | ||
} | ||
|
||
[Theory] | ||
[InlineData(ErrorType.Failure)] | ||
[InlineData(ErrorType.Unexpected)] | ||
[InlineData(ErrorType.Validation)] | ||
[InlineData(ErrorType.Conflict)] | ||
[InlineData(ErrorType.NotFound)] | ||
[InlineData(ErrorType.Authorization)] | ||
[InlineData(ErrorType.PreconditionFailed)] | ||
public async Task PrintHelloWorldCommand_ShouldReturnCorrectErrorException(ErrorType errorType) | ||
{ | ||
// Arrange | ||
var client = _factory.CreateClient(); | ||
var serviceCollection = new ServiceCollection(); | ||
serviceCollection.AddCQRS(typeof(ThrowErrorCommand).Assembly) | ||
.AddRemoteHttpServer(client) | ||
.ConfigureRemoteCommandProcessing<ThrowErrorCommand>("api/commands/throw-error"); | ||
var commands = serviceCollection.BuildServiceProvider().GetRequiredService<ICommands>(); | ||
var throwErrorCommand = new ThrowErrorCommand(errorType); | ||
|
||
// Act | ||
var exception = await Record.ExceptionAsync(() => commands.RunAsync(throwErrorCommand)); | ||
|
||
// Assert | ||
exception.Should().NotBeNull().And.BeAssignableTo<ErrorException>() | ||
.Which.ErrorType.Should().Be(errorType); | ||
exception?.GetType().Name.Should().Be($"{errorType}ErrorException"); | ||
} | ||
} |
71 changes: 71 additions & 0 deletions
71
...CQRS.Extensions.FastEndpoints.UnitTests/Extensions/PostProcessorContextExtensionsTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
using FastEndpoints; | ||
using FluentAssertions; | ||
using Moq; | ||
using Wemogy.CQRS.Extensions.FastEndpoints.Extensions; | ||
|
||
namespace Wemogy.CQRS.Extensions.FastEndpoints.UnitTests.Extensions; | ||
|
||
public class PostProcessorContextExtensionsTests | ||
{ | ||
/// <summary> | ||
/// This method checks if the MarkExceptionAsHandled implementation from FastEndpoints is working as expected | ||
/// This is required, because the implementation is only internal accessible, so we need to hardcode the key | ||
/// </summary> | ||
[Fact] | ||
public void MarkExceptionAsHandled_ShouldHaveTheExpectedImplementation() | ||
{ | ||
// Arrange | ||
var defaultHttpContext = new DefaultHttpContext(); | ||
var mockContext = new Mock<IPostProcessorContext> | ||
{ | ||
// enable CallBase to tell Moq to use the default interface implementations (like MarkExceptionAsHandled) | ||
CallBase = true | ||
}; | ||
mockContext.SetupGet(m => m.HttpContext).Returns(defaultHttpContext); | ||
|
||
// Act | ||
mockContext.Object.MarkExceptionAsHandled(); | ||
|
||
// Assert | ||
defaultHttpContext.Items.Should().ContainSingle(x => ReferenceEquals(x.Key, "3") && x.Value == null); | ||
} | ||
|
||
[Fact] | ||
public void IsExceptionHandled_ShouldBeTrueIfMarkExceptionAsHandledWasCalled() | ||
{ | ||
// Arrange | ||
var defaultHttpContext = new DefaultHttpContext(); | ||
var mockContext = new Mock<IPostProcessorContext> | ||
{ | ||
// enable CallBase to tell Moq to use the default interface implementations (like MarkExceptionAsHandled) | ||
CallBase = true | ||
}; | ||
mockContext.SetupGet(m => m.HttpContext).Returns(defaultHttpContext); | ||
mockContext.Object.MarkExceptionAsHandled(); | ||
|
||
// Act | ||
var result = mockContext.Object.IsExceptionHandled(); | ||
|
||
// Assert | ||
result.Should().BeTrue(); | ||
} | ||
|
||
[Fact] | ||
public void IsExceptionHandled_ShouldBeFalseIfMarkExceptionAsHandledWasNotCalled() | ||
{ | ||
// Arrange | ||
var defaultHttpContext = new DefaultHttpContext(); | ||
var mockContext = new Mock<IPostProcessorContext> | ||
{ | ||
// enable CallBase to tell Moq to use the default interface implementations (like MarkExceptionAsHandled) | ||
CallBase = true | ||
}; | ||
mockContext.SetupGet(m => m.HttpContext).Returns(defaultHttpContext); | ||
|
||
// Act | ||
var result = mockContext.Object.IsExceptionHandled(); | ||
|
||
// Assert | ||
result.Should().BeFalse(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
16 changes: 0 additions & 16 deletions
16
...dpoints/Wemogy.CQRS.Extensions.FastEndpoints/Extensions/ExceptionInformationExtensions.cs
This file was deleted.
Oops, something went wrong.
18 changes: 18 additions & 0 deletions
18
...dpoints/Wemogy.CQRS.Extensions.FastEndpoints/Extensions/PostProcessorContextExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
using FastEndpoints; | ||
|
||
namespace Wemogy.CQRS.Extensions.FastEndpoints.Extensions; | ||
|
||
public static class PostProcessorContextExtensions | ||
{ | ||
/// <summary> | ||
/// The MarkExceptionAsHandled method add the CtxKey.EdiIsHandled key to the HttpContext.Items dictionary | ||
/// This method checks if the CtxKey.EdiIsHandled key is present in the HttpContext.Items dictionary | ||
/// </summary> | ||
public static bool IsExceptionHandled(this IPostProcessorContext context) | ||
{ | ||
// The CtxKey class is an internal class of FastEndpoints which means that we can't access it | ||
// for that reason we hardcoded the value of the key | ||
// The PostProcessorContextExtensionsTests class tests this implementation, so if the key changes the tests will fail | ||
return context.HttpContext.Items.ContainsKey("3"); | ||
} | ||
} |
5 changes: 5 additions & 0 deletions
5
...mogy.CQRS.Extensions.FastEndpoints/PostProcessors/CqrsEndpointExceptionPostProcessor`1.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
namespace Wemogy.CQRS.Extensions.FastEndpoints.PostProcessors; | ||
|
||
public class CqrsEndpointExceptionPostProcessor<TRequest> : CqrsEndpointExceptionPostProcessor<TRequest, object?> | ||
{ | ||
} |
28 changes: 28 additions & 0 deletions
28
...mogy.CQRS.Extensions.FastEndpoints/PostProcessors/CqrsEndpointExceptionPostProcessor`2.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
using System.Net; | ||
using FastEndpoints; | ||
using Wemogy.Core.Errors.Exceptions; | ||
using Wemogy.Core.Errors.Extensions; | ||
using Wemogy.Core.Json.ExceptionInformation; | ||
using Wemogy.CQRS.Extensions.FastEndpoints.Extensions; | ||
|
||
namespace Wemogy.CQRS.Extensions.FastEndpoints.PostProcessors; | ||
|
||
public class CqrsEndpointExceptionPostProcessor<TRequest, TResponse> : IPostProcessor<TRequest, TResponse> | ||
{ | ||
public Task PostProcessAsync(IPostProcessorContext<TRequest, TResponse> context, CancellationToken ct) | ||
{ | ||
if (!context.HasExceptionOccurred) | ||
{ | ||
return Task.CompletedTask; | ||
} | ||
|
||
var exception = context.ExceptionDispatchInfo.SourceException; | ||
|
||
var statusCode = (exception as ErrorException)?.ErrorType.ToHttpStatusCode() ?? HttpStatusCode.InternalServerError; | ||
|
||
context.MarkExceptionAsHandled(); | ||
|
||
context.HttpContext.Response.Headers.AppendJsonTypeHeader<ExceptionInformation>(); | ||
return context.HttpContext.Response.SendStringAsync(exception.ToJson(), (int)statusCode, cancellation: ct); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.