Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion source/EasyWay.WebApi/Internals/WebApiResultMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public IResult Map(CommandResult commandResult)
{
CommandErrorEnum.None => Results.Ok(),
CommandErrorEnum.Validation => Results.BadRequest(commandResult.ValidationErrors),
CommandErrorEnum.BrokenBusinessRule => Results.Conflict(new BrokenBusinessRuleExceptionResponse(commandResult.Exception)),
CommandErrorEnum.BrokenBusinessRule => Results.Conflict(new BrokenBusinessRuleExceptionResponse(commandResult.BrokenBusinessRuleException)),
CommandErrorEnum.ConcurrencyConflict => Results.StatusCode(409),
CommandErrorEnum.OperationCanceled => Results.StatusCode(499),
CommandErrorEnum.NotFound => Results.StatusCode(404),
Expand Down
8 changes: 6 additions & 2 deletions source/EasyWay/CommandResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ public sealed class CommandResult

internal IDictionary<string, string[]> ValidationErrors;

internal BrokenBusinessRuleException? BrokenBusinessRuleException;

internal Exception? Exception;

private CommandResult()
Expand Down Expand Up @@ -38,7 +40,7 @@ private CommandResult(BrokenBusinessRuleException brokenBusinessRuleException)
{
Error = CommandErrorEnum.BrokenBusinessRule;
ValidationErrors = new Dictionary<string, string[]>();
Exception = brokenBusinessRuleException;
BrokenBusinessRuleException = brokenBusinessRuleException;
}

private CommandResult(ConcurrencyException concurrencyException)
Expand Down Expand Up @@ -81,6 +83,8 @@ public sealed class CommandResult<TOperationResult>

internal IDictionary<string, string[]> ValidationErrors;

internal BrokenBusinessRuleException? BrokenBusinessRuleException;

internal Exception? Exception;

private CommandResult(TOperationResult operationResult)
Expand Down Expand Up @@ -112,7 +116,7 @@ private CommandResult(BrokenBusinessRuleException brokenBusinessRuleException)
OperationResult = null;
Error = CommandErrorEnum.BrokenBusinessRule;
ValidationErrors = new Dictionary<string, string[]>();
Exception = brokenBusinessRuleException;
BrokenBusinessRuleException = brokenBusinessRuleException;
}

private CommandResult(ConcurrencyException concurrencyException)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,33 @@
{
var logger = _serviceProvider.GetRequiredService<EasyWayLogger<TModule>>();

//TODO begin scope (correlation Id)
//TODO begin scope (correlation Id, userId)

logger.Executing(command);

try
{
var result = await _decoratedCommandExecutor.Execute<TModule, TCommand>(command, cancellationToken);

logger.Executed();
switch (result.Error)
{
case CommandErrorEnum.None: logger.Successed(); break;
case CommandErrorEnum.Validation: logger.Validation(result.ValidationErrors); break;
case CommandErrorEnum.BrokenBusinessRule: logger.BrokenBusinessRule(result.BrokenBusinessRuleException.BrokenBusinessRule); break;

Check warning on line 38 in source/EasyWay/Internals/Commands/Commands/CommandExecutorLoggerDecorator.cs

View workflow job for this annotation

GitHub Actions / Build & Tests

Dereference of a possibly null reference.
case CommandErrorEnum.ConcurrencyConflict: logger.ConcurrencyConflict(result.Exception); break;

Check warning on line 39 in source/EasyWay/Internals/Commands/Commands/CommandExecutorLoggerDecorator.cs

View workflow job for this annotation

GitHub Actions / Build & Tests

Possible null reference argument for parameter 'exception' in 'void EasyWayLogger<TModule>.ConcurrencyConflict(Exception exception)'.
case CommandErrorEnum.OperationCanceled: logger.OperationCanceled(); break;
case CommandErrorEnum.NotFound: logger.NotFound(); break;
case CommandErrorEnum.Forbidden: logger.Forbidden(); break;
default: logger.UnexpectedException(result.Exception); break;
}

return result;
}
catch (Exception ex)
{
logger.UnexpectedException(ex);
throw;

return CommandResult.UnknownException(ex);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
namespace EasyWay.Internals.Commands.CommandsWithResult
using EasyWay.Internals.Queries.Loggers;
using Microsoft.Extensions.DependencyInjection;

namespace EasyWay.Internals.Commands.CommandsWithResult
{
internal sealed class CommandWithOperationResultExecutorLoggerDecorator : ICommandWithOperationResultExecutor
{
Expand All @@ -14,12 +17,41 @@ public CommandWithOperationResultExecutorLoggerDecorator(
_serviceProvider = serviceProvider;
}

public Task<CommandResult<TOperationResult>> Command<TModule, TCommand, TOperationResult>(TCommand command, CancellationToken cancellationToken = default)
public async Task<CommandResult<TOperationResult>> Command<TModule, TCommand, TOperationResult>(TCommand command, CancellationToken cancellationToken = default)
where TModule : EasyWayModule
where TCommand : Command<TOperationResult>
where TOperationResult : OperationResult
{
return _decoratedCommandExecutor.Command<TModule, TCommand, TOperationResult>(command, cancellationToken);
var logger = _serviceProvider.GetRequiredService<EasyWayLogger<TModule>>();

//TODO begin scope (correlation Id, userId)

logger.Executing(command);

try
{
var result = await _decoratedCommandExecutor.Command<TModule, TCommand, TOperationResult>(command, cancellationToken);

switch (result.Error)
{
case CommandErrorEnum.None: logger.Successed(result.OperationResult); break;
case CommandErrorEnum.Validation: logger.Validation(result.ValidationErrors); break;
case CommandErrorEnum.BrokenBusinessRule: logger.BrokenBusinessRule(result.BrokenBusinessRuleException.BrokenBusinessRule); break;
case CommandErrorEnum.ConcurrencyConflict: logger.ConcurrencyConflict(result.Exception); break;
case CommandErrorEnum.OperationCanceled: logger.OperationCanceled(); break;
case CommandErrorEnum.NotFound: logger.NotFound(); break;
case CommandErrorEnum.Forbidden: logger.Forbidden(); break;
default: logger.UnexpectedException(result.Exception); break;
}

return result;
}
catch (Exception ex)
{
logger.UnexpectedException(ex);

return CommandResult<TOperationResult>.UnknownException(ex);
}
}
}
}
33 changes: 25 additions & 8 deletions source/EasyWay/Internals/Loggers/EasyWayLogger.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Microsoft.Extensions.Logging;
using EasyWay.Internals.BusinessRules;
using Microsoft.Extensions.Logging;

namespace EasyWay.Internals.Queries.Loggers
{
Expand All @@ -9,18 +10,34 @@ internal sealed partial class EasyWayLogger<TModule>

public EasyWayLogger(ILogger<TModule> logger) => _logger = logger;

//TODO scope logger CorrelationId (ScopeId)

[LoggerMessage(0, LogLevel.Information, "Executing {@component}", SkipEnabledCheck = true)]
public partial void Executing(object component);

[LoggerMessage(1, LogLevel.Information, "Executed", SkipEnabledCheck = true)]
public partial void Executed();
[LoggerMessage(1, LogLevel.Information, "Successed", SkipEnabledCheck = true)]
public partial void Successed();

[LoggerMessage(2, LogLevel.Information, "Successed: {@result}", SkipEnabledCheck = true)]
public partial void Successed(object result);

[LoggerMessage(3, LogLevel.Information, "Validation error: {@validatonErrors}", SkipEnabledCheck = true)]
public partial void Validation(IDictionary<string, string[]> validatonErrors);

[LoggerMessage(4, LogLevel.Information, "Broken business rule: {@brokenBusinessRule}", SkipEnabledCheck = true)]
public partial void BrokenBusinessRule(BusinessRule brokenBusinessRule);

[LoggerMessage(5, LogLevel.Information, "Not found", SkipEnabledCheck = true)]
public partial void NotFound();

[LoggerMessage(6, LogLevel.Information, "Operation canceled", SkipEnabledCheck = true)]
public partial void OperationCanceled();

[LoggerMessage(7, LogLevel.Warning, "Forbidden", SkipEnabledCheck = true)]
public partial void Forbidden();

[LoggerMessage(2, LogLevel.Information, "Failed", SkipEnabledCheck = true)]
public partial void Failed();
[LoggerMessage(8, LogLevel.Warning, "Concurrency conflict", SkipEnabledCheck = true)]
public partial void ConcurrencyConflict(Exception exception);

[LoggerMessage(3, LogLevel.Error, "Unexpected exception", SkipEnabledCheck = true)]
[LoggerMessage(500, LogLevel.Error, "Unexpected exception", SkipEnabledCheck = true)]
public partial void UnexpectedException(Exception exception);
}
}
18 changes: 14 additions & 4 deletions source/EasyWay/Internals/Queries/QueryExecutorLoggerDecorator.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using EasyWay.Internals.Queries.Loggers;
using EasyWay.Internals.Queries.Results;
using Microsoft.Extensions.DependencyInjection;

namespace EasyWay.Internals.Queries
Expand All @@ -24,23 +25,32 @@
{
var logger = _serviceProvider.GetRequiredService<EasyWayLogger<TModule>>();

//TODO begin scope (correlation Id)
//TODO begin scope (correlation Id, userId)

logger.Executing(query);

try
{
var result = await _decoratedQueryExecutor.Execute<TModule, TQuery, TReadModel>(query, cancellationToken);

logger.Executed();
switch (result.Error)
{
case QueryErrorEnum.None: logger.Successed(result.ReadModel); break;

Check warning on line 38 in source/EasyWay/Internals/Queries/QueryExecutorLoggerDecorator.cs

View workflow job for this annotation

GitHub Actions / Build & Tests

Possible null reference argument for parameter 'result' in 'void EasyWayLogger<TModule>.Successed(object result)'.
case QueryErrorEnum.Validation: logger.Validation(result.ValidationErrors); break;
case QueryErrorEnum.OperationCanceled: logger.OperationCanceled(); break;
case QueryErrorEnum.NotFound: logger.NotFound(); break;
case QueryErrorEnum.Forbidden: logger.Forbidden(); break;
default: logger.UnexpectedException(result.Exception); break;

Check warning on line 43 in source/EasyWay/Internals/Queries/QueryExecutorLoggerDecorator.cs

View workflow job for this annotation

GitHub Actions / Build & Tests

Possible null reference argument for parameter 'exception' in 'void EasyWayLogger<TModule>.UnexpectedException(Exception exception)'.
}

return result;
}
catch (Exception ex)
{
logger.UnexpectedException(ex);
throw;
}

return QueryResult<TReadModel>.UnknownException(ex);
}
}
}
}
Loading