Improve error handling and resource cleanup in action handler

Refactored InvokeRecActionViewCommandHandler to enhance error handling by logging exceptions and conditionally rethrowing based on ErrorAction. Simplified NTLM HttpClient/handler management for proper disposal. Improved code structure and formatting for clarity.
This commit is contained in:
2026-03-24 17:02:06 +01:00
parent a707cce6e4
commit 894b7bb070

View File

@@ -1,4 +1,4 @@
using MediatR; using MediatR;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using ReC.Application.Common.Constants; using ReC.Application.Common.Constants;
@@ -31,28 +31,26 @@ public class InvokeRecActionViewCommandHandler(
public async Task Handle(InvokeRecActionViewCommand request, CancellationToken cancel) public async Task Handle(InvokeRecActionViewCommand request, CancellationToken cancel)
{ {
var action = request.Action; var action = request.Action;
if (action.RestType is not RestType restType)
throw new DataIntegrityException(
$"Rec action could not be invoked because the RestType value is null. " +
$"ProfileId: {action.ProfileId}, " +
$"Id: {action.Id}"
);
using var httpReq = CreateHttpRequestMessage(restType, action.EndpointUri);
if (action.Body is not null)
httpReq.Content = new StringContent(action.Body);
if (action.Headers is not null)
foreach (var header in action.Headers)
httpReq.Headers.Add(header.Key, header.Value);
HttpClient? ntlmClient = null; HttpClient? ntlmClient = null;
HttpClientHandler? ntlmHandler = null;
try try
{ {
if (action.RestType is not RestType restType)
throw new DataIntegrityException(
$"Rec action could not be invoked because the RestType value is null. " +
$"ProfileId: {action.ProfileId}, " +
$"Id: {action.Id}"
);
using var httpReq = CreateHttpRequestMessage(restType, action.EndpointUri);
if (action.Body is not null)
httpReq.Content = new StringContent(action.Body);
if (action.Headers is not null)
foreach (var header in action.Headers)
httpReq.Headers.Add(header.Key, header.Value);
switch (action.EndpointAuthType) switch (action.EndpointAuthType)
{ {
case EndpointAuthType.NoAuth: case EndpointAuthType.NoAuth:
@@ -116,12 +114,12 @@ public class InvokeRecActionViewCommandHandler(
endpointAuthPassword, endpointAuthPassword,
action.EndpointAuthDomain); action.EndpointAuthDomain);
var credentialCache = new CredentialCache { { httpReq.RequestUri!, "NTLM", credentials } }; var credentialCache = new CredentialCache { { httpReq.RequestUri!, "NTLM", credentials } };
ntlmHandler = new HttpClientHandler var ntlmHandler = new HttpClientHandler
{ {
Credentials = credentialCache, Credentials = credentialCache,
UseDefaultCredentials = false UseDefaultCredentials = false
}; };
ntlmClient = new HttpClient(ntlmHandler); ntlmClient = new HttpClient(ntlmHandler, disposeHandler: true);
} }
break; break;
@@ -139,7 +137,7 @@ public class InvokeRecActionViewCommandHandler(
); );
} }
using var http = ntlmClient ?? clientFactory.CreateClient(Http.ClientName); var http = ntlmClient ?? clientFactory.CreateClient(Http.ClientName);
using var response = await http.SendAsync(httpReq, cancel); using var response = await http.SendAsync(httpReq, cancel);
var resBody = await response.Content.ReadAsStringAsync(cancel); var resBody = await response.Content.ReadAsStringAsync(cancel);
var resHeaders = response.Headers.ToDictionary(); var resHeaders = response.Headers.ToDictionary();
@@ -154,9 +152,20 @@ public class InvokeRecActionViewCommandHandler(
Body = resBody Body = resBody
}, cancel); }, cancel);
} }
catch(Exception ex)
{
await sender.Send(new InsertResultCommand()
{
ActionId = action.Id,
Error = ex.ToString()
}, cancel);
if (action.ErrorAction == ErrorAction.Stop)
throw;
}
finally finally
{ {
ntlmHandler?.Dispose(); ntlmClient?.Dispose();
} }
} }