10 Commits

Author SHA1 Message Date
e816340755 Improve HTTP status info formatting in result views
Replaced the simple status code string with ResultView.FormatHttpStatusInfo for the Info field, providing more descriptive HTTP status information. Added the ReC.Domain.Views namespace import to support this change.
2026-04-02 21:02:32 +02:00
64e8e2a5cc Add HTTP status formatting/parsing to ResultView
Added FormatHttpStatusInfo and ParseHttpStatusInfo methods to ResultView for converting between HttpStatusCode values and "statusCode statusName" strings. Included supporting Regex and necessary using directives.
2026-04-02 21:02:15 +02:00
0edf2626a7 Add Info property to InsertResultCommand in test
The InsertResultProcedure_runs_via_mediator test now sets the Info property to "200" when initializing InsertResultCommand, ensuring the command includes this field during testing.
2026-04-02 20:39:05 +02:00
1d16276a8a Add InfoDetail property to InsertResultCommand
Added a nullable string property InfoDetail to InsertResultCommand to allow storing additional detailed information with each result. No other changes were made.
2026-04-02 20:38:55 +02:00
4eae092031 Update result handling and error status in command handler
Removed unused statusCode variable and now store HTTP status code as a string in the Info field. Changed exception handling to set Status to RecStatus.Error instead of RecStatus.Failed.
2026-04-02 20:38:01 +02:00
ce7fe03525 Add InfoDetail property to ResultView model
Added the InfoDetail property to the ResultView class, mapping it to the RESULT_INFO_DETAIL column in the database. This allows for storing and retrieving additional result detail information.
2026-04-02 20:37:46 +02:00
a93780df5c Add Info, InfoDetail, and Error to UpdateResultDto
Extended UpdateResultDto with Info, InfoDetail, and Error fields. Updated UpdateObjectProcedureHandler to pass these new properties as parameters to the stored procedure, enabling richer result and error reporting in database updates.
2026-04-02 20:37:29 +02:00
d7a2a01421 Add pRESULT_INFO_DETAIL param to InsertObjectProcedureHandler
Added support for the pRESULT_INFO_DETAIL parameter in the database command, mapping it from request.Result?.InfoDetail to enable passing detailed result information to the stored procedure.
2026-04-02 20:36:51 +02:00
329e441ede Standardize InsertResultCommand status and info fields
Updated InsertResultCommand usage to replace QuerySuccess with OK and Failed with Error for status reporting. Changed Info to InfoDetail for both preprocessing and postprocessing behaviors to ensure consistent result and error handling.
2026-04-02 20:36:35 +02:00
1ad7ff3b34 Add InfoDetail property to ResultViewDto
Added a nullable string property InfoDetail with a public setter to the ResultViewDto record for storing additional detailed information. No changes were made to the existing Error property.
2026-04-02 20:36:03 +02:00
10 changed files with 56 additions and 11 deletions

View File

@@ -23,9 +23,9 @@ public class PostprocessingBehavior(IRecDbContext context, ISender sender) : IPi
await sender.Send(new InsertResultCommand()
{
Status = RecStatus.QuerySuccess,
Status = RecStatus.OK,
ActionId = request.Action.Id,
Info = info,
InfoDetail = info,
Type = ResultType.Post
}, cancel);
}
@@ -36,7 +36,7 @@ public class PostprocessingBehavior(IRecDbContext context, ISender sender) : IPi
await sender.Send(new InsertResultCommand()
{
Status = RecStatus.Failed,
Status = RecStatus.Error,
ActionId = request.Action.Id,
Error = error,
Type = ResultType.Post

View File

@@ -20,9 +20,9 @@ public class PreprocessingBehavior(IRecDbContext context, ISender sender) : IPip
await sender.Send(new InsertResultCommand()
{
Status = RecStatus.QuerySuccess,
Status = RecStatus.OK,
ActionId = request.Action.Id,
Info = JsonSerializer.Serialize(result),
InfoDetail = JsonSerializer.Serialize(result),
Type = ResultType.Pre
}, cancel);
}
@@ -31,7 +31,7 @@ public class PreprocessingBehavior(IRecDbContext context, ISender sender) : IPip
{
await sender.Send(new InsertResultCommand()
{
Status = RecStatus.Failed,
Status = RecStatus.Error,
ActionId = request.Action.Id,
Error = ex.ToString(),
Type = ResultType.Pre

View File

@@ -26,6 +26,8 @@ public record ResultViewDto
public string? Info { get; set; }
public string? InfoDetail { get; set; }
public string? Error { get; set; }
public string? AddedWho { get; init; }

View File

@@ -81,6 +81,7 @@ public class InsertObjectProcedureHandler(IRepository repo, IOptionsMonitor<SqlE
.Add("pRESULT_HEADER", request.Result?.Header)
.Add("pRESULT_BODY", request.Result?.Body)
.Add("pRESULT_INFO", request.Result?.Info)
.Add("pRESULT_INFO_DETAIL", request.Result?.InfoDetail)
.Add("pRESULT_ERROR", request.Result?.Error)
.Add("pENDPOINT_PARAMS_ACTIVE", request.EndpointParams?.Active)
.Add("pENDPOINT_PARAMS_DESCRIPTION", request.EndpointParams?.Description)

View File

@@ -6,4 +6,7 @@ public record UpdateResultDto
public short? StatusId { get; set; }
public string? Header { get; set; }
public string? Body { get; set; }
public string? Info { get; set; }
public string? InfoDetail { get; set; }
public string? Error { get; set; }
}

View File

@@ -88,7 +88,10 @@ public class UpdateObjectProcedureHandler(IRepository repo, IOptionsMonitor<SqlE
.Add("pRESULT_ACTION_ID", request.Result.ActionId)
.Add("pRESULT_STATUS_ID", request.Result.StatusId, SqlDbType.SmallInt)
.Add("pRESULT_HEADER", request.Result.Header)
.Add("pRESULT_BODY", request.Result.Body);
.Add("pRESULT_BODY", request.Result.Body)
.Add("pRESULT_INFO", request.Result.Info)
.Add("pRESULT_INFO_DETAIL", request.Result.InfoDetail)
.Add("pRESULT_ERROR", request.Result.Error);
try
{

View File

@@ -7,6 +7,7 @@ using ReC.Application.Common.Exceptions;
using ReC.Application.Common.Options;
using ReC.Application.Results.Commands;
using ReC.Domain.Constants;
using ReC.Domain.Views;
using System.Net;
using System.Net.Http.Headers;
using System.Text;
@@ -142,14 +143,13 @@ public class InvokeRecActionViewCommandHandler(
var resBody = await response.Content.ReadAsStringAsync(cancel);
var resHeaders = response.Headers.ToDictionary();
var statusCode = (short)response.StatusCode;
await sender.Send(new InsertResultCommand()
{
Status = response.StatusCode.ToRecStatus(),
ActionId = action.Id,
Header = JsonSerializer.Serialize(resHeaders, options: new() { WriteIndented = false }),
Body = resBody,
Info = ResultView.FormatHttpStatusInfo(response.StatusCode),
Type = ResultType.Main
}, cancel);
}
@@ -157,7 +157,7 @@ public class InvokeRecActionViewCommandHandler(
{
await sender.Send(new InsertResultCommand()
{
Status = RecStatus.Failed,
Status = RecStatus.Error,
ActionId = action.Id,
Error = ex.ToString(),
Type = ResultType.Main

View File

@@ -11,6 +11,7 @@ public record InsertResultCommand : IInsertProcedure
public string? Header { get; set; }
public string? Body { get; set; }
public string? Info { get; set; }
public string? InfoDetail { get; set; }
public string? Error { get; set; }
public required ResultType Type { get; set; }
}

View File

@@ -1,6 +1,8 @@
using ReC.Domain.Constants;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Net;
using System.Text.RegularExpressions;
namespace ReC.Domain.Views;
@@ -45,6 +47,9 @@ public class ResultView
[Column("RESULT_INFO")]
public string? Info { get; set; }
[Column("RESULT_INFO_DETAIL")]
public string? InfoDetail { get; set; }
[Column("RESULT_ERROR")]
public string? Error { get; set; }
@@ -59,4 +64,34 @@ public class ResultView
[Column("CHANGED_WHEN")]
public DateTime? ChangedWhen { get; set; }
private static readonly Regex HttpStatusInfoRegex = new(@"^(\d{3})\s+(.+)$", RegexOptions.Compiled);
/// <summary>
/// Formats an <see cref="HttpStatusCode"/> into a string in the form "statusCode statusName".
/// For example, <see cref="HttpStatusCode.NotFound"/> becomes "404 Not Found".
/// </summary>
public static string FormatHttpStatusInfo(HttpStatusCode statusCode)
{
var code = (int)statusCode;
var name = statusCode.ToString();
var displayName = Regex.Replace(name, "(?<!^)([A-Z])", " $1");
return $"{code} {displayName}";
}
/// <summary>
/// Parses an Info string in the form "statusCode statusName" back into its components.
/// Returns <c>null</c> if the string does not match the expected format.
/// </summary>
public static (int StatusCode, string StatusName)? ParseHttpStatusInfo(string? info)
{
if (info is null)
return null;
var match = HttpStatusInfoRegex.Match(info);
if (!match.Success)
return null;
return (int.Parse(match.Groups[1].Value), match.Groups[2].Value);
}
}

View File

@@ -25,7 +25,7 @@ public class ResultProcedureTests : RecApplicationTestBase
[Test]
public async Task InsertResultProcedure_runs_via_mediator()
{
var procedure = new InsertResultCommand { ActionId = 1, Status = HttpStatusCode.OK.ToRecStatus(), Header = "h", Body = "b", Type = Domain.Constants.ResultType.Main };
var procedure = new InsertResultCommand { ActionId = 1, Status = HttpStatusCode.OK.ToRecStatus(), Header = "h", Body = "b", Info = "200", Type = Domain.Constants.ResultType.Main };
var (sender, scope) = CreateScopedSender();
using var _ = scope;