feat: add batch action execution response tracking

- Introduce BatchRecActionViewResponse to track execution metrics
- Add SuccessCount and FailureCount properties to monitor execution results
- Change InvokeBatchRecActionViewsCommand to return response data
- Update RecActionController to return Ok with response instead of Accepted
- Improve error handling to distinguish RecActionException from unexpected errors
- Consolidate exception handling logic for ErrorAction.Continue scenarios
This commit is contained in:
2026-08-03 17:11:25 +02:00
parent 003f4c60f6
commit 8e0ee6fbfa
2 changed files with 26 additions and 19 deletions

View File

@@ -21,12 +21,11 @@ public class RecActionController(IMediator mediator) : ControllerBase
[ProducesResponseType(StatusCodes.Status202Accepted)] [ProducesResponseType(StatusCodes.Status202Accepted)]
public async Task<IActionResult> Invoke([FromRoute] long profileId, [FromBody] InvokeReferences references, CancellationToken cancel = default) public async Task<IActionResult> Invoke([FromRoute] long profileId, [FromBody] InvokeReferences references, CancellationToken cancel = default)
{ {
await mediator.Send(new InvokeBatchRecActionViewsCommand return Ok(await mediator.Send(new InvokeBatchRecActionViewsCommand
{ {
ProfileId = profileId, ProfileId = profileId,
References = references References = references
}, cancel); }, cancel));
return Accepted();
} }
#region CRUD #region CRUD

View File

@@ -6,16 +6,26 @@ using ReC.Domain.Constants;
namespace ReC.Application.RecActions.Commands; namespace ReC.Application.RecActions.Commands;
public record InvokeBatchRecActionViewsCommand : IRequest public record InvokeBatchRecActionViewsCommand : IRequest<BatchRecActionViewResponse>
{ {
public long ProfileId { get; init; } public long ProfileId { get; init; }
public required InvokeReferences References { get; init; } public required InvokeReferences References { get; init; }
} }
public class InvokeRecActionViewsCommandHandler(ISender sender, ILogger<InvokeRecActionViewsCommandHandler>? logger = null) : IRequestHandler<InvokeBatchRecActionViewsCommand> public record BatchRecActionViewResponse
{ {
public async Task Handle(InvokeBatchRecActionViewsCommand request, CancellationToken cancel) public int TotalActionCount => SuccessCount + FailureCount;
public int SuccessCount { get; internal set; } = 0;
public int FailureCount { get; internal set; } = 0;
}
public class InvokeRecActionViewsCommandHandler(ISender sender, ILogger<InvokeRecActionViewsCommandHandler>? logger = null) : IRequestHandler<InvokeBatchRecActionViewsCommand, BatchRecActionViewResponse>
{ {
public async Task<BatchRecActionViewResponse> Handle(InvokeBatchRecActionViewsCommand request, CancellationToken cancel)
{
var res = new BatchRecActionViewResponse();
var actions = await sender.Send(new ReadRecActionViewQuery() { ProfileId = request.ProfileId }, cancel); var actions = await sender.Send(new ReadRecActionViewQuery() { ProfileId = request.ProfileId }, cancel);
foreach (var action in actions) foreach (var action in actions)
@@ -27,31 +37,29 @@ public class InvokeRecActionViewsCommandHandler(ISender sender, ILogger<InvokeRe
Action = action, Action = action,
References = request.References References = request.References
}, cancel); }, cancel);
}
catch (RecActionException ex) res.SuccessCount += 1;
{
switch (action.ErrorAction)
{
case ErrorAction.Continue:
logger?.LogWarning(ex, "Rec action failed but continuing. ActionId: {ActionId}, ProfileId: {ProfileId}", ex.ActionId, ex.ProfileId);
break;
default:
// Rethrow the exception to stop processing further actions
throw;
}
} }
catch (Exception ex) catch (Exception ex)
{ {
switch (action.ErrorAction) switch (action.ErrorAction)
{ {
case ErrorAction.Continue: case ErrorAction.Continue:
if (ex is RecActionException recEx)
logger?.LogWarning(ex, "Rec action failed but continuing. ActionId: {ActionId}, ProfileId: {ProfileId}", recEx.ActionId, recEx.ProfileId);
else
logger?.LogError(ex, "Unexpected error during rec action. ActionId: {ActionId}, ProfileId: {ProfileId}", action.Id, action.ProfileId); logger?.LogError(ex, "Unexpected error during rec action. ActionId: {ActionId}, ProfileId: {ProfileId}", action.Id, action.ProfileId);
break; break;
default: default:
// Rethrow the exception to stop processing further actions // Rethrow the exception to stop processing further actions
throw; throw;
} }
res.FailureCount += 1;
} }
} }
return res;
} }
} }