From ff3908cdd27715470b4987fcead7d1793f1549c4 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Fri, 28 Nov 2025 23:24:36 +0100 Subject: [PATCH 1/8] Support HTTP request body in InvokeRecActionCommandHandler Added logic to handle non-null `request.Body` in HTTP requests. Introduced a `StringContent` object to encapsulate the body content and assigned it to the `Content` property of the HTTP request. This ensures that the request body is included when sending data to the specified endpoint. --- .../RecActions/Commands/InvokeRecActionCommand.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/ReC.Application/RecActions/Commands/InvokeRecActionCommand.cs b/src/ReC.Application/RecActions/Commands/InvokeRecActionCommand.cs index f40ea25..7f341cf 100644 --- a/src/ReC.Application/RecActions/Commands/InvokeRecActionCommand.cs +++ b/src/ReC.Application/RecActions/Commands/InvokeRecActionCommand.cs @@ -40,6 +40,12 @@ public class InvokeRecActionCommandHandler( .ToHttpMethod() .ToHttpRequestMessage(request.EndpointUri); + if(request.Body is not null) + { + using var reqBody = new StringContent(request.Body); + httpReq.Content = reqBody; + } + using var response = await http.SendAsync(httpReq, cancel); var body = await response.Content.ReadAsStringAsync(cancel); var headers = response.Headers.ToDictionary(); From 97c57d4fb13dcf112ddaf2badff20ca79968c914 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Fri, 28 Nov 2025 23:32:28 +0100 Subject: [PATCH 2/8] Add validation for BodyQuery result in Handle method Previously, the `Handle` method in `BodyQueryBehavior` did not validate the `BodyQuery` result before setting `action.Body`. This change introduces a check to ensure that the result and its `RawBody` are not null. If either is null, an `InvalidOperationException` is thrown with a clear error message. This ensures `action.Body` is only set when a valid result is retrieved, improving robustness and preventing potential null reference issues. --- src/ReC.Application/Common/Behaviors/BodyQueryBehavior.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/ReC.Application/Common/Behaviors/BodyQueryBehavior.cs b/src/ReC.Application/Common/Behaviors/BodyQueryBehavior.cs index 77ed91c..3c533fc 100644 --- a/src/ReC.Application/Common/Behaviors/BodyQueryBehavior.cs +++ b/src/ReC.Application/Common/Behaviors/BodyQueryBehavior.cs @@ -12,9 +12,13 @@ public class BodyQueryBehavior(IRecDbContext dbContext) : IPipelineB { if (action.BodyQuery is null) return await next(cancel); - + var result = await dbContext.BodyQueryResults.FromSqlRaw(action.BodyQuery).FirstOrDefaultAsync(cancel); - action.Body = result?.RawBody; + + if (result is null || result.RawBody is null) + throw new InvalidOperationException("Body query did not return a result or returned a null REQUEST_BODY."); + + action.Body = result.RawBody; return await next(cancel); } From cc787f445acd3f72d41db1c8683932d6a0acca70 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Fri, 28 Nov 2025 23:37:09 +0100 Subject: [PATCH 3/8] Improve null-checking and error handling in Handle Simplified null-checks in the `Handle` method of the `BodyQueryBehavior` class using the null-conditional operator. Enhanced the exception message to include `ProfileId` and `ActionId` for better debugging context when `result?.RawBody` is null. --- src/ReC.Application/Common/Behaviors/BodyQueryBehavior.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/ReC.Application/Common/Behaviors/BodyQueryBehavior.cs b/src/ReC.Application/Common/Behaviors/BodyQueryBehavior.cs index 3c533fc..fa77ffb 100644 --- a/src/ReC.Application/Common/Behaviors/BodyQueryBehavior.cs +++ b/src/ReC.Application/Common/Behaviors/BodyQueryBehavior.cs @@ -9,14 +9,16 @@ public class BodyQueryBehavior(IRecDbContext dbContext) : IPipelineB where TRecAction : RecActionDto { public async Task Handle(TRecAction action, RequestHandlerDelegate next, CancellationToken cancel) - { + { if (action.BodyQuery is null) return await next(cancel); var result = await dbContext.BodyQueryResults.FromSqlRaw(action.BodyQuery).FirstOrDefaultAsync(cancel); - if (result is null || result.RawBody is null) - throw new InvalidOperationException("Body query did not return a result or returned a null REQUEST_BODY."); + if (result?.RawBody is null) + throw new InvalidOperationException( + $"Body query did not return a result or returned a null REQUEST_BODY. " + + $"ProfileId: {action.ProfileId}, ActionId: {action.ActionId}."); action.Body = result.RawBody; From ff53be5d13f00b65aaf66af20c4f33fdc161705b Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Fri, 28 Nov 2025 23:41:35 +0100 Subject: [PATCH 4/8] Throw exception for null RawHeader in HeaderQueryBehavior Previously, the code continued execution when the RawHeader property of the query result was null. This change introduces an InvalidOperationException to handle this case, ensuring that the absence of a valid RawHeader is treated as an error. The exception message includes ProfileId and ActionId for better debugging context. --- src/ReC.Application/Common/Behaviors/HeaderQueryBehavior.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ReC.Application/Common/Behaviors/HeaderQueryBehavior.cs b/src/ReC.Application/Common/Behaviors/HeaderQueryBehavior.cs index 8149416..4b66322 100644 --- a/src/ReC.Application/Common/Behaviors/HeaderQueryBehavior.cs +++ b/src/ReC.Application/Common/Behaviors/HeaderQueryBehavior.cs @@ -18,7 +18,9 @@ public class HeaderQueryBehavior(IRecDbContext dbContext, ILogger>(result.RawHeader); From 0d801466cf36409779bf32ae51e9d963a1a56c7b Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Sat, 29 Nov 2025 00:36:03 +0100 Subject: [PATCH 5/8] Add properties for query tracking and post-processing Added `IsReturnedNoData` property as a tuple to track the state of `BodyQuery` and `HeaderQuery` data returns. Introduced `PostprocessingQuery` property to support initialization of post-processing queries. These changes enhance the functionality of the `RecActionDto` class by enabling better query handling and processing capabilities. --- src/ReC.Application/Common/Dto/RecActionDto.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ReC.Application/Common/Dto/RecActionDto.cs b/src/ReC.Application/Common/Dto/RecActionDto.cs index f636510..76af15f 100644 --- a/src/ReC.Application/Common/Dto/RecActionDto.cs +++ b/src/ReC.Application/Common/Dto/RecActionDto.cs @@ -60,6 +60,8 @@ public record RecActionDto public string? Body { get; set; } + public (bool BodyQuery, bool HeaderQuery) IsReturnedNoData = (false, false); + public string? PostprocessingQuery { get; init; } public UriBuilder ToEndpointUriBuilder() From e0736ff6dfff4420b7addfaeb30f5fd12e8971f1 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Sat, 29 Nov 2025 00:55:43 +0100 Subject: [PATCH 6/8] Improve HeaderQueryBehavior error handling and logging Updated HeaderQueryBehavior to handle null or missing REQUEST_HEADER gracefully by logging warnings and setting action.IsReturnedNoData.HeaderQuery to true instead of throwing exceptions. Enhanced log messages for failed RawHeader deserialization to improve clarity and added pipeline continuity by calling await next(cancel). Refactored log formatting for consistency. --- .../Common/Behaviors/HeaderQueryBehavior.cs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/ReC.Application/Common/Behaviors/HeaderQueryBehavior.cs b/src/ReC.Application/Common/Behaviors/HeaderQueryBehavior.cs index 4b66322..a331340 100644 --- a/src/ReC.Application/Common/Behaviors/HeaderQueryBehavior.cs +++ b/src/ReC.Application/Common/Behaviors/HeaderQueryBehavior.cs @@ -18,15 +18,24 @@ public class HeaderQueryBehavior(IRecDbContext dbContext, ILogger>(result.RawHeader); if(headerDict is null) { - logger?.LogWarning("Failed to deserialize header query result: {RawHeader}. Profile ID: {ProfileId}, Action ID: {ActionId}", result.RawHeader, action.ProfileId, action.ActionId); + logger?.LogWarning( + "Header JSON deserialization returned null. RawHeader: {RawHeader}, ProfileId: {ProfileId}, ActionId: {ActionId}", + result.RawHeader, action.ProfileId, action.ActionId); + + action.IsReturnedNoData.HeaderQuery = true; + return await next(cancel); } From 07afcf3aa2fa863908d461b571e7695486608f32 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Sat, 29 Nov 2025 01:12:03 +0100 Subject: [PATCH 7/8] Add logging for unexpected BodyQuery and IsReturnedNoData Improve observability by adding a warning log when `request.BodyQuery` is not null but `request.IsReturnedNoData.BodyQuery` is false. The log message highlights potential issues, such as skipped `BodyQueryBehavior` execution or missing control steps, and includes `ProfileId` and `ActionId` for better debugging context. --- .../RecActions/Commands/InvokeRecActionCommand.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/ReC.Application/RecActions/Commands/InvokeRecActionCommand.cs b/src/ReC.Application/RecActions/Commands/InvokeRecActionCommand.cs index 7f341cf..135700e 100644 --- a/src/ReC.Application/RecActions/Commands/InvokeRecActionCommand.cs +++ b/src/ReC.Application/RecActions/Commands/InvokeRecActionCommand.cs @@ -45,6 +45,17 @@ public class InvokeRecActionCommandHandler( using var reqBody = new StringContent(request.Body); httpReq.Content = reqBody; } + else if(request.BodyQuery is not null && !request.IsReturnedNoData.BodyQuery) + { + logger?.LogWarning( + "Although BodyQuery returns null, the IsReturnedNoData variable has not been set to TRUE. " + + "This indicates that BodyQueryBehavior has not been executed or that the relevant control step has been skipped. " + + "The relevant behavior must be verified to ensure that the process does not produce unexpected conditions. " + + "ProfileId: {ProfileId}, ActionId: {ActionId}", + request.ProfileId, + request.ActionId + ); + } using var response = await http.SendAsync(httpReq, cancel); var body = await response.Content.ReadAsStringAsync(cancel); From b78b3e43f4ed79deafbaa0d913d520d7280a3cbb Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Mon, 1 Dec 2025 09:45:41 +0100 Subject: [PATCH 8/8] Add support for custom headers in HTTP requests Enhanced HTTP request handling by adding support for dynamically including custom headers from the `request.Headers` collection. Implemented a null check to ensure robustness and prevent null reference exceptions when processing headers. This change improves flexibility and customization of HTTP requests. --- .../RecActions/Commands/InvokeRecActionCommand.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ReC.Application/RecActions/Commands/InvokeRecActionCommand.cs b/src/ReC.Application/RecActions/Commands/InvokeRecActionCommand.cs index 135700e..be24672 100644 --- a/src/ReC.Application/RecActions/Commands/InvokeRecActionCommand.cs +++ b/src/ReC.Application/RecActions/Commands/InvokeRecActionCommand.cs @@ -57,6 +57,10 @@ public class InvokeRecActionCommandHandler( ); } + if (request.Headers is not null) + foreach (var header in request.Headers) + httpReq.Headers.Add(header.Key, header.Value); + using var response = await http.SendAsync(httpReq, cancel); var body = await response.Content.ReadAsStringAsync(cancel); var headers = response.Headers.ToDictionary();