feat(logging): improve exception handling and add comprehensive logging
JobExceptionHandlingBehavior: - Add ILogger for diagnostic output - Change ResultText to include full exception details (ToString()) - Log JobException with warning level including ProfileId, JobName, ProcessName, BatchId - Return default instead of re-throwing to allow graceful handling ReCRequestExecutionBehavior: - Convert to primary constructor pattern - Add ILogger for request tracking - Store RecActionResult in command for later use - Log successful ReC requests with detailed metrics (TotalActionCount, ActionExceptionCount) - Improve error handling and logging
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
using ECMJobRunner.Application.ProfileHistories.Commands;
|
using ECMJobRunner.Application.ProfileHistories.Commands;
|
||||||
using ECMJobRunner.Domain.ValueObjects;
|
using ECMJobRunner.Domain.ValueObjects;
|
||||||
using MediatR;
|
using MediatR;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
@@ -14,7 +15,8 @@ namespace ECMJobRunner.Application.Profiles.Commands.Behaviors;
|
|||||||
/// <typeparam name="TRequest">The type of the MediatR request</typeparam>
|
/// <typeparam name="TRequest">The type of the MediatR request</typeparam>
|
||||||
/// <typeparam name="TResponse">The type of the MediatR response</typeparam>
|
/// <typeparam name="TResponse">The type of the MediatR response</typeparam>
|
||||||
/// <param name="Sender">MediatR sender used to dispatch the <see cref="ECMJobRunner.Application.ProfileHistories.Commands.CreateProfileHistoryCommand"/></param>
|
/// <param name="Sender">MediatR sender used to dispatch the <see cref="ECMJobRunner.Application.ProfileHistories.Commands.CreateProfileHistoryCommand"/></param>
|
||||||
public class JobExceptionHandlingBehavior<TRequest, TResponse>(ISender Sender) : IPipelineBehavior<TRequest, TResponse> where TRequest : notnull
|
/// <param name="Logger">Logger for diagnostic output.</param>
|
||||||
|
public class JobExceptionHandlingBehavior<TRequest, TResponse>(ISender Sender, ILogger<JobExceptionHandlingBehavior<TRequest, TResponse>> Logger) : IPipelineBehavior<TRequest, TResponse> where TRequest : notnull
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Handles the pipeline behavior
|
/// Handles the pipeline behavior
|
||||||
@@ -36,12 +38,14 @@ public class JobExceptionHandlingBehavior<TRequest, TResponse>(ISender Sender) :
|
|||||||
{
|
{
|
||||||
ProfileId = ex.ProfileId,
|
ProfileId = ex.ProfileId,
|
||||||
Result = ResultType.Ok,
|
Result = ResultType.Ok,
|
||||||
ResultText = ex.Message,
|
ResultText = ex.ToString(),
|
||||||
AddedWho = "ECMJobRunner"
|
AddedWho = "ECMJobRunner"
|
||||||
};
|
};
|
||||||
await Sender.Send(cmd, cancellationToken);
|
await Sender.Send(cmd, cancellationToken);
|
||||||
|
|
||||||
throw;
|
Logger.LogWarning(ex, "JobException caught in JobExceptionHandlingBehavior for ProfileId {ProfileId}, JobName {JobName}, ProcessName {ProcessName}, BatchId {BatchId}", ex.ProfileId, ex.JobName, ex.ProcessName, ex.BatchId);
|
||||||
|
|
||||||
|
return default!;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using ECMJobRunner.Application.Common.Exceptions;
|
|||||||
using ECMJobRunner.Application.Common.Options;
|
using ECMJobRunner.Application.Common.Options;
|
||||||
using ECMJobRunner.Application.Profiles.Commands;
|
using ECMJobRunner.Application.Profiles.Commands;
|
||||||
using MediatR;
|
using MediatR;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using ReC.Client;
|
using ReC.Client;
|
||||||
using ReC.Client.Api;
|
using ReC.Client.Api;
|
||||||
@@ -18,22 +19,15 @@ namespace ECMJobRunner.Application.Profiles.Commands.Behaviors
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="TRequest">The request type</typeparam>
|
/// <typeparam name="TRequest">The request type</typeparam>
|
||||||
/// <typeparam name="TResponse">The response type</typeparam>
|
/// <typeparam name="TResponse">The response type</typeparam>
|
||||||
public class ReCRequestExecutionBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
|
/// <remarks>
|
||||||
|
/// Initializes a new instance of ReCRequestExecutionBehavior
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="ReCClient">ReC client for HTTP requests</param>
|
||||||
|
/// <param name="options">DEX job configuration options</param>
|
||||||
|
public class ReCRequestExecutionBehavior<TRequest, TResponse>(ReCClient ReCClient, IOptions<DexJobOptions> options, ILogger<ReCRequestExecutionBehavior<TRequest, TResponse>> Logger) : IPipelineBehavior<TRequest, TResponse>
|
||||||
where TRequest : notnull
|
where TRequest : notnull
|
||||||
{
|
{
|
||||||
private readonly ReCClient _reCClient;
|
private readonly DexJobOptions Options = options.Value;
|
||||||
private readonly DexJobOptions _options;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of ReCRequestExecutionBehavior
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="reCClient">ReC client for HTTP requests</param>
|
|
||||||
/// <param name="options">DEX job configuration options</param>
|
|
||||||
public ReCRequestExecutionBehavior(ReCClient reCClient, IOptions<DexJobOptions> options)
|
|
||||||
{
|
|
||||||
_reCClient = reCClient;
|
|
||||||
_options = options.Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Handles the pipeline behavior
|
/// Handles the pipeline behavior
|
||||||
@@ -57,14 +51,23 @@ namespace ECMJobRunner.Application.Profiles.Commands.Behaviors
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await _reCClient.RecActions.InvokeAsync(command.Job.ProfileId, new InvokeReferences()
|
command.RecActionResult = await ReCClient.RecActions.InvokeAsync(command.Job.ProfileId, new InvokeReferences()
|
||||||
{
|
{
|
||||||
BatchId = command.BatchId,
|
BatchId = command.BatchId,
|
||||||
}, cancel);
|
}, cancel);
|
||||||
|
|
||||||
|
Logger.LogInformation(
|
||||||
|
"ReC request completed successfully. Profile ID: {ProfileId} | Job name: {JobName} | Batch ID: {BatchId} | Total action count: {TotalActionCount} | Action exception count: {ActionExceptionCount}",
|
||||||
|
command.Job.ProfileId,
|
||||||
|
command.Job.Name,
|
||||||
|
command.BatchId,
|
||||||
|
command.RecActionResult?.TotalActionCount ?? 0,
|
||||||
|
command.RecActionResult?.ActionExceptionCount ?? 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
if (_options.Error.ReCRequest.OnSending == ErrorAction.Stop)
|
if (Options.Error.ReCRequest.OnSending == ErrorAction.Stop)
|
||||||
{
|
{
|
||||||
throw new JobHttpException(
|
throw new JobHttpException(
|
||||||
profileId: command.Job.ProfileId,
|
profileId: command.Job.ProfileId,
|
||||||
|
|||||||
Reference in New Issue
Block a user