public void EqualsIErrorBuilder_WhenObjectIsErrorBuilderList_ReturnsTrue() { var eb = new ErrorBuilder( ErrorCode.Unknown, new ErrorData.ExceptionData(new Exception()) ); var el = new ErrorBuilderList(new[] { eb }); Assert.True(eb.Equals((IErrorBuilder)el)); }
public void AsString_JoinsAllErrors() { var errorBuilders = new[] { new ErrorBuilder(ErrorCode.RequirementNotMet, "req"), new ErrorBuilder(ErrorCode.ConflictingParameters, "1", "2") }; var eb = new ErrorBuilderList(errorBuilders); Assert.Equal( eb.ToString(), $"{errorBuilders[0].AsString}{ErrorSeparator}{errorBuilders[1].AsString}" ); }
public void WithLocation_AddsLocationToErrors() { var errorBuilders = new[] { new ErrorBuilder(ErrorCode.DirectoryNotFound, "directory"), new ErrorBuilder(ErrorCode.MissingContext, "context") }; var eb = new ErrorBuilderList(errorBuilders); var el = new ErrorLocation("test"); var errors = eb.WithLocation(el).GetAllErrors(); foreach (var err in errors) { Assert.Equal(el, err.Location); } }
/// <inheritdoc /> public async Task <Result <Unit, IErrorBuilder> > RunExternalProcess( string processPath, IErrorHandler errorHandler, IEnumerable <string> arguments, IReadOnlyDictionary <string, string> environmentVariables, Encoding encoding, IStateMonad stateMonad, IStep?callingStep, CancellationToken cancellationToken) { var absolutePath = GetAbsolutePath(processPath); if (absolutePath.IsFailure) { return(absolutePath.ConvertFailure <Unit>()); } var argumentString = string.Join(' ', arguments.Select(EncodeParameterArgument)); LogSituation.ExternalProcessStarted.Log( stateMonad, callingStep, absolutePath.Value, argumentString ); using var pProcess = new Process { StartInfo = { FileName = absolutePath.Value, Arguments = argumentString, UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true, WindowStyle = ProcessWindowStyle.Hidden, //don't display a window CreateNoWindow = true, StandardErrorEncoding = encoding, StandardOutputEncoding = encoding } }; foreach (var(key, value) in environmentVariables) { pProcess.StartInfo.EnvironmentVariables.Add( key, value ); } foreach (var(key, value) in pProcess.StartInfo.Environment) { LogSituation.EnvironmentVariable.Log(stateMonad, callingStep, key, value); } var errors = new List <IErrorBuilder>(); try { pProcess.Start(); var channelReader = StreamChannelHelper.ToChannelReader( (pProcess.StandardOutput, StreamSource.Output), (pProcess.StandardError, StreamSource.Error) ); await foreach (var(line, streamSource) in channelReader.ReadAllAsync(cancellationToken) ) { if (streamSource == StreamSource.Error) { var errorText = string.IsNullOrWhiteSpace(line) ? "Unknown Error" : line; if (errorHandler.ShouldIgnoreError(errorText)) { stateMonad.Log(LogLevel.Warning, line, callingStep); } else { errors.Add(new ErrorBuilder(ErrorCode.ExternalProcessError, errorText)); } } else { stateMonad.Log(LogLevel.Information, line, callingStep); } } // ReSharper disable once MethodHasAsyncOverloadWithCancellation - run on a separate thread pProcess.WaitForExit(); } #pragma warning disable CA1031 // Do not catch general exception types catch (Exception e) { errors.Add(new ErrorBuilder(e, ErrorCode.ExternalProcessError)); } #pragma warning restore CA1031 // Do not catch general exception types if (errors.Any()) { var e = ErrorBuilderList.Combine(errors); return(Result.Failure <Unit, IErrorBuilder>(e)); } return(Unit.Default); }
/// <summary> /// Attempts to apply this schema to an entity. /// </summary> public Result <Maybe <Entity>, IErrorBuilder> ApplyToEntity( Entity entity, IStep callingStep, IStateMonad stateMonad, Maybe <ErrorBehavior> errorBehaviorOverride) { var remainingProperties = Properties .ToDictionary( x => x.Key, x => x.Value, StringComparer.OrdinalIgnoreCase ); var newProperties = new List <EntityProperty>(); var errors = new List <IErrorBuilder>(); var warnings = new List <IErrorBuilder>(); var changed = false; var returnEntity = true; void HandleError(IErrorBuilder error, ErrorBehavior eb) { switch (eb) { case ErrorBehavior.Fail: errors.Add(error); break; case ErrorBehavior.Error: warnings.Add(error); returnEntity = false; break; case ErrorBehavior.Warning: warnings.Add(error); break; case ErrorBehavior.Skip: returnEntity = false; break; case ErrorBehavior.Ignore: break; default: throw new ArgumentOutOfRangeException(nameof(eb), eb, null); } } ErrorBehavior generalErrorBehavior; if (errorBehaviorOverride.HasValue) { generalErrorBehavior = errorBehaviorOverride.Value; } else { generalErrorBehavior = DefaultErrorBehavior; } foreach (var entityProperty in entity) { if (remainingProperties.Remove(entityProperty.Name, out var schemaProperty)) { var convertResult = entityProperty.BestValue.TryConvert( this, entityProperty.Name, schemaProperty, entity ); if (convertResult.IsSuccess) { if (convertResult.Value.changed) { changed = true; var newProperty = new EntityProperty( entityProperty.Name, entityProperty.BaseValue, convertResult.Value.value, entityProperty.Order ); newProperties.Add(newProperty); } else { newProperties.Add(entityProperty); } } else { ErrorBehavior errorBehavior; if (errorBehaviorOverride.HasValue) { errorBehavior = errorBehaviorOverride.Value; } else if (schemaProperty.ErrorBehavior != null) { errorBehavior = schemaProperty.ErrorBehavior.Value; } else { errorBehavior = DefaultErrorBehavior; } HandleError(convertResult.Error, errorBehavior); } } else { switch (ExtraProperties) { case ExtraPropertyBehavior.Fail: { changed = true; var errorBuilder = ErrorCode.SchemaViolationUnexpectedProperty.ToErrorBuilder( entityProperty.Name, entity ); HandleError(errorBuilder, ErrorBehavior.Fail); break; } case ExtraPropertyBehavior.Remove: { changed = true; break; } case ExtraPropertyBehavior.Warn: { changed = true; var errorBuilder = ErrorCode.SchemaViolationUnexpectedProperty.ToErrorBuilder( entityProperty.Name, entity ); HandleError(errorBuilder, ErrorBehavior.Warning); break; } case ExtraPropertyBehavior.Allow: { newProperties.Add(entityProperty); break; } default: throw new ArgumentOutOfRangeException(); } } } foreach (var(key, _) in remainingProperties .Where(x => x.Value.Multiplicity is Multiplicity.ExactlyOne or Multiplicity.AtLeastOne)) { var error = ErrorCode.SchemaViolationMissingProperty.ToErrorBuilder(key, entity); HandleError(error, generalErrorBehavior); } if (errors.Any()) { var errorList = ErrorBuilderList.Combine(errors); return(Result.Failure <Maybe <Entity>, IErrorBuilder>(errorList)); } if (warnings.Any()) { var warningList = ErrorBuilderList.Combine(warnings); LogSituation.SchemaViolation.Log(stateMonad, callingStep, warningList.AsString); } if (!returnEntity) { return(Maybe <Entity> .None); } if (!changed) { return(Maybe <Entity> .From(entity)); } var resultEntity = new Entity(newProperties); return(Maybe <Entity> .From(resultEntity)); }