Skip to content

Instantly share code, notes, and snippets.

@vkhorikov
Last active April 15, 2019 21:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vkhorikov/c0018b922575d1005e8d7bd2dd3e8594 to your computer and use it in GitHub Desktop.
Save vkhorikov/c0018b922575d1005e8d7bd2dd3e8594 to your computer and use it in GitHub Desktop.
CQRS and exception handling
public class EditPersonalInfoCommandHandler : ICommandHandler<EditPersonalInfoCommand>
{
public Result Handle(EditPersonalInfoCommand command)
{
for (int i = 0; ; i++)
{
try
{
var unitOfWork = new UnitOfWork(_sessionFactory);
Student student = unitOfWork.GetStudentById(command.Id);
student.Name = command.Name;
student.Email = command.Email;
unitOfWork.Commit();
return Result.Ok();
}
catch (Exception ex)
{
if (i >= _config.NumberOfDatabaseRetries || !IsDatabaseException(ex))
throw;
}
}
}
}
[DatabaseRetry]
public class EditPersonalInfoCommandHandler : ICommandHandler<EditPersonalInfoCommand>
{
public Result Handle(EditPersonalInfoCommand command)
{
var unitOfWork = new UnitOfWork(_sessionFactory);
Student student = unitOfWork.GetStudentById(command.Id);
student.Name = command.Name;
student.Email = command.Email;
unitOfWork.Commit();
return Result.Ok();
}
}
public sealed class DatabaseRetryDecorator<TCommand> : ICommandHandler<TCommand>
where TCommand : ICommand
{
private readonly ICommandHandler<TCommand> _handler;
private readonly Config _config;
public DatabaseRetryDecorator(ICommandHandler<TCommand> handler, Config config)
{
_config = config;
_handler = handler;
}
public Result Handle(TCommand command)
{
for (int i = 0; ; i++)
{
try
{
Result result = _handler.Handle(command);
return result;
}
catch (Exception ex)
{
if (i >= _config.NumberOfDatabaseRetries || !IsDatabaseException(ex))
throw;
}
}
}
private bool IsDatabaseException(Exception exception)
{
string message = exception.InnerException?.Message;
if (message == null)
return false;
return message.Contains("The connection is broken and recovery is not possible")
|| message.Contains("error occurred while establishing a connection");
}
}
public Result Handle(TCommand command)
{
for (int i = 0; ; i++)
{
Result result = _handler.Handle(command);
if (result.Error == Errors.DatabaseException)
{
if (i >= _config.NumberOfDatabaseRetries)
throw new Exception();
continue;
}
return result;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment