Exemple #1
0
        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));
        }
Exemple #2
0
        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}"
                );
        }
Exemple #3
0
        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);
        }
Exemple #5
0
        /// <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));
        }