Skip to content

Commit 7dcfcc6

Browse files
authored
Merge pull request #52 from PandaTechAM/development
Performance boost
2 parents 92839bb + 9042845 commit 7dcfcc6

File tree

9 files changed

+62
-52
lines changed

9 files changed

+62
-52
lines changed

src/ResponseCrafter/ApiExceptionHandler.cs renamed to src/ResponseCrafter/ExceptionHandlers/Http/ApiExceptionHandler.cs

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,16 @@
88
using ResponseCrafter.Dtos;
99
using ResponseCrafter.Enums;
1010
using ResponseCrafter.Extensions;
11+
using ResponseCrafter.Helpers;
1112
using ResponseCrafter.HttpExceptions;
1213
using ResponseCrafter.Options;
1314
using static ResponseCrafter.Helpers.ExceptionMessageBuilder;
1415
using IExceptionHandler = Microsoft.AspNetCore.Diagnostics.IExceptionHandler;
1516

16-
namespace ResponseCrafter;
17+
namespace ResponseCrafter.ExceptionHandlers.Http;
1718

18-
public class ApiExceptionHandler : IExceptionHandler
19+
internal class ApiExceptionHandler : IExceptionHandler
1920
{
20-
private const string DefaultMessage = "something_went_wrong_please_try_again_later_and_or_contact_it_support";
21-
22-
private const string ConcurrencyMessage =
23-
"a_concurrency_conflict_occurred._please_reload_the_resource_and_try_you_update_again";
24-
2521
private readonly NamingConvention _convention;
2622
private readonly ILogger<ApiExceptionHandler> _logger;
2723
private readonly string _visibility;
@@ -32,14 +28,7 @@ public ApiExceptionHandler(ILogger<ApiExceptionHandler> logger,
3228
{
3329
_logger = logger;
3430
_convention = convention.NamingConvention;
35-
_visibility = configuration["ResponseCrafterVisibility"]!;
36-
37-
38-
if (string.IsNullOrWhiteSpace(_visibility) || (_visibility != "Private" && _visibility != "Public"))
39-
{
40-
_visibility = "Public";
41-
_logger.LogWarning("Visibility configuration was not available. Defaulted to 'Public'.");
42-
}
31+
_visibility = configuration.GetResponseCrafterVisibility(_logger);
4332
}
4433

4534
public async ValueTask<bool> TryHandleAsync(HttpContext httpContext,
@@ -73,7 +62,7 @@ public async ValueTask<bool> TryHandleAsync(HttpContext httpContext,
7362
private async Task HandleDbConcurrencyExceptionAsync(HttpContext httpContext, CancellationToken cancellationToken)
7463
{
7564
var exception =
76-
new ConflictException(ConcurrencyMessage.ConvertCase(_convention));
65+
new ConflictException(ExceptionMessages.ConcurrencyMessage.ConvertCase(_convention));
7766
await HandleApiExceptionAsync(httpContext, exception, cancellationToken);
7867
}
7968

@@ -150,7 +139,7 @@ private async Task HandleGeneralExceptionAsync(HttpContext httpContext,
150139
Instance = CreateRequestPath(httpContext),
151140
StatusCode = 500,
152141
Type = "InternalServerError",
153-
Message = DefaultMessage.ConvertCase(_convention)
142+
Message = ExceptionMessages.DefaultMessage.ConvertCase(_convention)
154143
};
155144

156145
if (_visibility == "Private")
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
namespace ResponseCrafter.ExceptionHandlers.SignalR;
2+
3+
public class HubArgument : IHubArgument
4+
{
5+
public string? InvocationId { get; set; }
6+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
namespace ResponseCrafter.ExceptionHandlers.SignalR;
2+
3+
internal interface IHubArgument
4+
{
5+
public string InvocationId { get; set; }
6+
}

src/ResponseCrafter/SignalRExceptionFilter.cs renamed to src/ResponseCrafter/ExceptionHandlers/SignalR/SignalRExceptionFilter.cs

Lines changed: 8 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,10 @@
1111
using ResponseCrafter.HttpExceptions;
1212
using ResponseCrafter.Options;
1313

14-
namespace ResponseCrafter;
14+
namespace ResponseCrafter.ExceptionHandlers.SignalR;
1515

1616
public class SignalRExceptionFilter : IHubFilter
1717
{
18-
private const string DefaultMessage = "something_went_wrong_please_try_again_later_and_or_contact_it_support";
19-
20-
private const string ConcurrencyMessage =
21-
"a_concurrency_conflict_occurred._please_reload_the_resource_and_try_you_update_again";
22-
2318
private readonly NamingConvention _convention;
2419
private readonly ILogger<SignalRExceptionFilter> _logger;
2520
private readonly string _visibility;
@@ -30,14 +25,7 @@ public SignalRExceptionFilter(ILogger<SignalRExceptionFilter> logger,
3025
{
3126
_logger = logger;
3227
_convention = convention.NamingConvention;
33-
_visibility = configuration["ResponseCrafterVisibility"]!;
34-
35-
36-
if (string.IsNullOrWhiteSpace(_visibility) || (_visibility != "Private" && _visibility != "Public"))
37-
{
38-
_visibility = "Public";
39-
_logger.LogWarning("Visibility configuration was not available. Defaulted to 'Public'.");
40-
}
28+
_visibility = configuration.GetResponseCrafterVisibility(_logger);
4129
}
4230

4331

@@ -48,12 +36,12 @@ public SignalRExceptionFilter(ILogger<SignalRExceptionFilter> logger,
4836

4937
try
5038
{
51-
invocationId = TryGetInvocationId(invocationContext);
39+
invocationId = TryGetInvocationId<HubArgument>(invocationContext);
5240
return await next(invocationContext);
5341
}
5442
catch (DbUpdateConcurrencyException)
5543
{
56-
var exception = new ConflictException(ConcurrencyMessage.ConvertCase(_convention));
44+
var exception = new ConflictException(ExceptionMessages.ConcurrencyMessage.ConvertCase(_convention));
5745
return await HandleApiExceptionAsync(invocationContext, exception, invocationId);
5846
}
5947
catch (GridifyException ex)
@@ -71,23 +59,14 @@ public SignalRExceptionFilter(ILogger<SignalRExceptionFilter> logger,
7159
}
7260
}
7361

74-
private static string TryGetInvocationId(HubInvocationContext hubInvocationContext)
62+
private static string TryGetInvocationId<T>(HubInvocationContext hubInvocationContext) where T : IHubArgument
7563
{
76-
if (hubInvocationContext.HubMethodArguments.Count != 1)
64+
if (hubInvocationContext.HubMethodArguments is not [T hubArgument])
7765
{
7866
throw new BadRequestException("Invalid hub method arguments. Expected a single HubArgument<T> parameter.");
7967
}
8068

81-
var hubArgument = hubInvocationContext.HubMethodArguments[0];
82-
var invocationIdProperty = hubArgument?.GetType()
83-
.GetProperty("InvocationId");
84-
85-
if (invocationIdProperty == null || invocationIdProperty.PropertyType != typeof(string))
86-
{
87-
throw new BadRequestException("Invalid hub method argument. Missing 'InvocationId' property.");
88-
}
89-
90-
var invocationId = invocationIdProperty.GetValue(hubArgument) as string;
69+
var invocationId = hubArgument.InvocationId;
9170
if (string.IsNullOrWhiteSpace(invocationId))
9271
{
9372
throw new BadRequestException("Invocation ID cannot be null, empty, or whitespace.");
@@ -138,7 +117,7 @@ private async Task<HubErrorResponse> HandleGeneralExceptionAsync(HubInvocationCo
138117
InvocationId = invocationId,
139118
Instance = invocationContext.HubMethodName,
140119
StatusCode = 500,
141-
Message = DefaultMessage.ConvertCase(_convention)
120+
Message = ExceptionMessages.DefaultMessage.ConvertCase(_convention)
142121
};
143122

144123
if (_visibility == "Private")
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using Microsoft.Extensions.Configuration;
2+
using Microsoft.Extensions.Logging;
3+
4+
namespace ResponseCrafter.Extensions;
5+
6+
internal static class ConfigurationExtensions
7+
{
8+
private const string ResponseCrafterVisibility = "ResponseCrafterVisibility";
9+
10+
public static string GetResponseCrafterVisibility<T>(this IConfiguration configuration, ILogger<T> logger)
11+
{
12+
var visibility = configuration[ResponseCrafterVisibility];
13+
14+
if (!string.IsNullOrWhiteSpace(visibility) && visibility is "Private" or "Public")
15+
{
16+
return visibility;
17+
}
18+
19+
logger.LogWarning("Visibility configuration was not available. Defaulted to 'Public'.");
20+
return "Public";
21+
}
22+
}

src/ResponseCrafter/Extensions/WebApplicationExtensions.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using Microsoft.AspNetCore.Builder;
22
using Microsoft.Extensions.DependencyInjection;
33
using ResponseCrafter.Enums;
4+
using ResponseCrafter.ExceptionHandlers.Http;
45
using ResponseCrafter.Options;
56

67
namespace ResponseCrafter.Extensions;
@@ -22,10 +23,7 @@ public static WebApplicationBuilder AddResponseCrafter(this WebApplicationBuilde
2223

2324
public static WebApplication UseResponseCrafter(this WebApplication app)
2425
{
25-
app.UseExceptionHandler(_ =>
26-
{
27-
}); //the lambda parameter is not needed it is just .net 8 bug which might be fixed in the future
28-
26+
app.UseExceptionHandler();
2927
return app;
3028
}
3129
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
namespace ResponseCrafter.Helpers;
2+
3+
internal static class ExceptionMessages
4+
{
5+
internal const string DefaultMessage = "something_went_wrong_please_try_again_later_and_or_contact_it_support";
6+
7+
internal const string ConcurrencyMessage =
8+
"a_concurrency_conflict_occurred._please_reload_the_resource_and_try_you_update_again";
9+
}

src/ResponseCrafter/ResponseCrafter.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@
88
<Copyright>MIT</Copyright>
99
<PackageIcon>pandatech.png</PackageIcon>
1010
<PackageReadmeFile>Readme.md</PackageReadmeFile>
11-
<Version>5.1.1</Version>
11+
<Version>5.1.2</Version>
1212
<PackageId>Pandatech.ResponseCrafter</PackageId>
1313
<PackageTags>Pandatech, library, exception handler, exception, middleware, Api response</PackageTags>
1414
<Title>ResponseCrafter</Title>
1515
<Description>Handling exceptions, custom Dtos.</Description>
1616
<RepositoryUrl>https://github.com/PandaTechAM/be-lib-response-crafter</RepositoryUrl>
17-
<PackageReleaseNotes>New naming convention added</PackageReleaseNotes>
17+
<PackageReleaseNotes>Performance boost</PackageReleaseNotes>
1818
</PropertyGroup>
1919

2020
<ItemGroup>

test/ResponseCrafter.Demo/Program.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using ResponseCrafter;
55
using ResponseCrafter.Demo.Hubs;
66
using ResponseCrafter.Enums;
7+
using ResponseCrafter.ExceptionHandlers.SignalR;
78
using ResponseCrafter.Extensions;
89

910
var builder = WebApplication.CreateBuilder(args);

0 commit comments

Comments
 (0)