Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Operation Result Refactoring #38

Merged
merged 6 commits into from
Jul 6, 2024
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 .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:

steps:
- uses: actions/checkout@v4

- name: Emit .NET 6.0 Framework Version
if: matrix.dotnet == '6.0.x'
run: echo "DOTNET_FX_VERSION=net6.0" >> $GITHUB_ENV
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pr-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:

steps:
- uses: actions/checkout@v4

- name: Emit .NET 6.0 Framework Version
if: matrix.dotnet == '6.0.x'
run: echo "DOTNET_FX_VERSION=net6.0" >> $GITHUB_ENV
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:

steps:
- uses: actions/checkout@v4

- name: Emit .NET 6.0 Framework Version
if: matrix.dotnet == '6.0.x'
run: echo "DOTNET_FX_VERSION=net6.0" >> $GITHUB_ENV
Expand Down
5 changes: 5 additions & 0 deletions src/Deveel.Repository.Manager/Data/EntityErrorCodes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ namespace Deveel.Data {
/// the type of error that occurred during an operation.
/// </summary>
public static class EntityErrorCodes {
/// <summary>
/// The application domain is unknown
/// </summary>
public const string UnknownDomain = "Unknown";

/// <summary>
/// The entity to be added or updated is not valid.
/// </summary>
Expand Down
35 changes: 20 additions & 15 deletions src/Deveel.Repository.Manager/Data/EntityManager_T2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,11 @@
/// </summary>
protected IEntityCache<TEntity>? EntityCache { get; }

/// <summary>
/// Gets the domain of the entities managed by the service.
/// </summary>
protected virtual string Domain => typeof(TEntity).Name;

/// <summary>
/// Gets an instance of the generator used to create the
/// keys for caching entities.
Expand Down Expand Up @@ -416,7 +421,7 @@
// TODO: dispose managed state (managed objects)
}

Repository = null;

Check warning on line 424 in src/Deveel.Repository.Manager/Data/EntityManager_T2.cs

View workflow job for this annotation

GitHub Actions / build (6.0.x)

Cannot convert null literal to non-nullable reference type.

Check warning on line 424 in src/Deveel.Repository.Manager/Data/EntityManager_T2.cs

View workflow job for this annotation

GitHub Actions / build (7.0.x)

Cannot convert null literal to non-nullable reference type.

Check warning on line 424 in src/Deveel.Repository.Manager/Data/EntityManager_T2.cs

View workflow job for this annotation

GitHub Actions / build (8.0.x)

Cannot convert null literal to non-nullable reference type.
Services = null;
disposedValue = true;
}
Expand Down Expand Up @@ -456,7 +461,7 @@
/// describes the error.
/// </returns>
protected virtual IOperationError OperationError(string errorCode, string? message = null)
=> ErrorFactory?.CreateError(errorCode, message) ?? new OperationError(errorCode, message);
=> ErrorFactory?.CreateError(errorCode, Domain, message) ?? new OperationError(errorCode, Domain, message);

/// <summary>
/// Creates a validation error object with the given
Expand All @@ -472,8 +477,8 @@
/// Returns an instance of <see cref="IValidationError"/> that
/// represents a validation error.
/// </returns>
protected virtual IValidationError ValidationError(string errorCode, IList<ValidationResult> validationResults)
=> ErrorFactory?.CreateValidationError(errorCode, validationResults) ?? new EntityValidationError(errorCode, validationResults);
protected virtual IValidationError ValidationError(string errorCode, IReadOnlyList<ValidationResult> validationResults)
=> ErrorFactory?.CreateValidationError(errorCode, Domain, validationResults) ?? new OperationValidationError(errorCode, Domain, validationResults);

/// <summary>
/// Creates an error object with the given code and message
Expand Down Expand Up @@ -524,8 +529,8 @@
/// Returns an instance of <see cref="OperationResult"/> that
/// represents a failed validation of an entity.
/// </returns>
/// <see cref="ValidationError(string, IList{ValidationResult})"/>
protected OperationResult ValidationFailed(string errorCode, IList<ValidationResult> validationResults)
/// <see cref="ValidationError(string, IReadOnlyList{ValidationResult})"/>
protected OperationResult ValidationFailed(string errorCode, IReadOnlyList<ValidationResult> validationResults)
=> OperationResult.Fail(ValidationError(errorCode, validationResults));

/// <summary>
Expand All @@ -546,7 +551,7 @@
/// represents an operation that has not modified the state of
/// an entity.
/// </returns>
protected OperationResult NotModified() => OperationResult.NotModified;
protected OperationResult NotChanged() => OperationResult.NotChanged;

/// <summary>
/// Validates the given entity before it is added or updated
Expand All @@ -561,7 +566,7 @@
/// Returns a list of <see cref="ValidationResult"/> that
/// describe the validation errors.
/// </returns>
protected virtual async Task<IList<ValidationResult>> ValidateAsync(TEntity entity, CancellationToken cancellationToken) {
protected virtual async Task<IReadOnlyList<ValidationResult>> ValidateAsync(TEntity entity, CancellationToken cancellationToken) {
if (EntityValidator == null)
return new List<ValidationResult>();

Expand Down Expand Up @@ -938,7 +943,7 @@

if (AreEqual(existing, entity)) {
Logger.LogEntityNotModified(typeof(TEntity), entityKey);
return NotModified();
return NotChanged();
}

var validation = await ValidateAsync(entity, token);
Expand All @@ -951,7 +956,7 @@

if (!await Repository.UpdateAsync(entity, token)) {
Logger.LogEntityNotModified(typeof(TEntity), entityKey);
return NotModified();
return NotChanged();
}

Logger.LogEntityUpdated(entityKey);
Expand Down Expand Up @@ -1012,7 +1017,7 @@

if (!await Repository.RemoveAsync(found, token)) {
Logger.LogEntityNotRemoved(typeof(TEntity), entityKey);
return NotModified();
return NotChanged();
}

await EvictAsync(entity, token);
Expand Down Expand Up @@ -1101,7 +1106,7 @@
return result;
} catch (Exception ex) {
LogEntityUnknownError(key, ex);
throw new OperationException(EntityErrorCodes.UnknownError, "Could not look for the entity", ex);
throw new OperationException(EntityErrorCodes.UnknownError, Domain, "Could not look for the entity", ex);
}
}

Expand Down Expand Up @@ -1142,7 +1147,7 @@
return await FilterableRepository.FindFirstAsync(query, GetCancellationToken(cancellationToken));
} catch (Exception ex) {
LogUnknownError(ex);
throw new OperationException(EntityErrorCodes.UnknownError, "Could not look for the entity", ex);
throw new OperationException(EntityErrorCodes.UnknownError, Domain, "Could not look for the entity", ex);
}
}

Expand Down Expand Up @@ -1197,7 +1202,7 @@
return await FilterableRepository.FindAllAsync(query, GetCancellationToken(cancellationToken));
} catch (Exception ex) {
LogUnknownError(ex);
throw new OperationException(EntityErrorCodes.UnknownError, "Could not look for the entity", ex);
throw new OperationException(EntityErrorCodes.UnknownError, Domain, "Could not look for the entity", ex);
}
}

Expand Down Expand Up @@ -1261,7 +1266,7 @@
return FilterableRepository.CountAsync(filter, GetCancellationToken(cancellationToken));
} catch (Exception ex) {
LogUnknownError(ex);
throw new OperationException(EntityErrorCodes.UnknownError, "Could not look for the entity", ex);
throw new OperationException(EntityErrorCodes.UnknownError, Domain, "Could not look for the entity", ex);
}
}

Expand Down Expand Up @@ -1313,7 +1318,7 @@
return await PageableRepository.GetPageAsync(query, GetCancellationToken(cancellationToken));
} catch (Exception ex) {
LogUnknownError(ex);
throw new OperationException(EntityErrorCodes.UnknownError, "Could not look for the entity", ex);
throw new OperationException(EntityErrorCodes.UnknownError, Domain, "Could not look for the entity", ex);
}
}
}
Expand Down
46 changes: 26 additions & 20 deletions src/Deveel.Repository.Manager/Data/IOperationErrorFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,25 +20,28 @@ namespace Deveel.Data {
/// that can be used to report errors in an operation.
/// </summary>
public interface IOperationErrorFactory {
/// <summary>
/// Creates an instance of <see cref="IOperationError"/>
/// with the given error code and message.
/// </summary>
/// <param name="errorCode">
/// The code that identifies the class of the error.
/// </param>
/// <param name="message">
/// A message that describes the error.
/// </param>
/// <returns>
/// Returns an instance of <see cref="IOperationError"/>
/// with the given error code and message.
/// </returns>
/// <exception cref="ArgumentNullException">
/// Thrown when the given <paramref name="errorCode"/> is <c>null</c>
/// or empty.
/// </exception>
IOperationError CreateError(string errorCode, string? message = null);
/// <summary>
/// Creates an instance of <see cref="IOperationError"/>
/// with the given error code and message.
/// </summary>
/// <param name="errorCode">
/// The code that identifies the class of the error.
/// </param>
/// <param name="domain">
/// The application domain that the error belongs to.
/// </param>
/// <param name="message">
/// A message that describes the error.
/// </param>
/// <returns>
/// Returns an instance of <see cref="IOperationError"/>
/// with the given error code and message.
/// </returns>
/// <exception cref="ArgumentNullException">
/// Thrown when the given <paramref name="errorCode"/> is <c>null</c>
/// or empty.
/// </exception>
IOperationError CreateError(string errorCode, string domain, string? message = null);

/// <summary>
/// Creates an instance of <see cref="IValidationError"/>
Expand All @@ -47,14 +50,17 @@ public interface IOperationErrorFactory {
/// <param name="errorCode">
/// The code that identifies the class of the error.
/// </param>
/// <param name="domain">
/// The application domain that the error belongs to.
/// </param>
/// <param name="validationResults">
/// The list of validation results that describe the error.
/// </param>
/// <returns>
/// Returns an instance of <see cref="IValidationError"/>
/// that represents a failed validation of an entity.
/// </returns>
IValidationError CreateValidationError(string errorCode, IList<ValidationResult> validationResults);
IValidationError CreateValidationError(string errorCode, string domain, IReadOnlyList<ValidationResult> validationResults);

/// <summary>
/// Creates an instance of <see cref="IOperationError"/>
Expand Down
16 changes: 9 additions & 7 deletions src/Deveel.Repository.Manager/Data/OperationErrorFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
/// <returns>
/// Returns an error code normalized to a standard format.
/// </returns>
protected virtual string ResolveErrorCode(string errorCode) {
protected virtual string ResolveErrorCode(string errorCode, string domain) {

Check warning on line 38 in src/Deveel.Repository.Manager/Data/OperationErrorFactory.cs

View workflow job for this annotation

GitHub Actions / build (6.0.x)

Parameter 'domain' has no matching param tag in the XML comment for 'OperationErrorFactory.ResolveErrorCode(string, string)' (but other parameters do)

Check warning on line 38 in src/Deveel.Repository.Manager/Data/OperationErrorFactory.cs

View workflow job for this annotation

GitHub Actions / build (7.0.x)

Parameter 'domain' has no matching param tag in the XML comment for 'OperationErrorFactory.ResolveErrorCode(string, string)' (but other parameters do)

Check warning on line 38 in src/Deveel.Repository.Manager/Data/OperationErrorFactory.cs

View workflow job for this annotation

GitHub Actions / build (8.0.x)

Parameter 'domain' has no matching param tag in the XML comment for 'OperationErrorFactory.ResolveErrorCode(string, string)' (but other parameters do)
return errorCode;
}

Expand All @@ -54,26 +54,28 @@
}

/// <inheritdoc/>
public virtual IOperationError CreateError(string errorCode, string? message = null)
=> new OperationError(ResolveErrorCode(errorCode), message == null ? GetErrorMessage(ResolveErrorCode(errorCode)) : message);
public virtual IOperationError CreateError(string errorCode, string domain, string? message = null)
=> new OperationError(ResolveErrorCode(errorCode, domain), domain, message == null ? GetErrorMessage(ResolveErrorCode(errorCode, domain)) : message);

/// <inheritdoc/>
public virtual IOperationError CreateError(Exception exception) {
string? errorCode = null, errorMessage = null;
string? errorCode = null, errorDomain = null, errorMessage = null;
if (exception is OperationException opError) {
errorCode = opError.ErrorCode;
errorDomain = opError.ErrorDomain;
errorMessage = opError.Message;
} else {
errorDomain = EntityErrorCodes.UnknownDomain;
errorCode = EntityErrorCodes.UnknownError;
errorMessage = exception.Message;
}

return new OperationError(errorCode, errorMessage);
return new OperationError(errorCode, errorDomain, errorMessage);
}

/// <inheritdoc/>
public virtual IValidationError CreateValidationError(string errorCode, IList<ValidationResult> validationResults) {
return new EntityValidationError(ResolveErrorCode(errorCode), validationResults);
public virtual IValidationError CreateValidationError(string errorCode, string domain, IReadOnlyList<ValidationResult> validationResults) {
return new OperationValidationError(ResolveErrorCode(errorCode, domain), domain, validationResults);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Deveel.Results" Version="1.0.1" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.1" Condition="'$(TargetFramework)' == 'net6.0'" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" Condition="'$(TargetFramework)' == 'net7.0'" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" Condition="'$(TargetFramework)' == 'net8.0'" />
Expand Down
48 changes: 0 additions & 48 deletions src/Deveel.Repository.Manager/EntityValidationError.cs

This file was deleted.

37 changes: 0 additions & 37 deletions src/Deveel.Repository.Manager/IOperationError.cs

This file was deleted.

Loading
Loading