diff --git a/sample/Ardalis.Result.Sample.Core/Services/BadResultService.cs b/sample/Ardalis.Result.Sample.Core/Services/BadResultService.cs new file mode 100644 index 0000000..4aee2bf --- /dev/null +++ b/sample/Ardalis.Result.Sample.Core/Services/BadResultService.cs @@ -0,0 +1,11 @@ +namespace Ardalis.Result.Sample.Core.Services; + +public class BadResultService +{ + public Result ReturnErrorWithMessage(string message) + { + var result = Result.Error(message); + return result; + } + +} diff --git a/sample/Ardalis.Result.Sample.Core/Services/WeatherServiceWithExceptions.cs b/sample/Ardalis.Result.Sample.Core/Services/WeatherServiceWithExceptions.cs index df14a5f..bea5c60 100644 --- a/sample/Ardalis.Result.Sample.Core/Services/WeatherServiceWithExceptions.cs +++ b/sample/Ardalis.Result.Sample.Core/Services/WeatherServiceWithExceptions.cs @@ -7,69 +7,67 @@ using System.Linq; using System.Threading.Tasks; -namespace Ardalis.Result.Sample.Core.Services +namespace Ardalis.Result.Sample.Core.Services; +public class WeatherServiceWithExceptions { - public class WeatherServiceWithExceptions + public WeatherServiceWithExceptions(IStringLocalizer stringLocalizer) { - public WeatherServiceWithExceptions(IStringLocalizer stringLocalizer) - { - _stringLocalizer = stringLocalizer; - } + _stringLocalizer = stringLocalizer; + } - private static readonly string[] Summaries = new[] + private static readonly string[] Summaries = new[] { - "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" - }; + "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" + }; - private IStringLocalizer _stringLocalizer; + private IStringLocalizer _stringLocalizer; - public Task> GetForecastAsync(ForecastRequestDto model) + public Task> GetForecastAsync(ForecastRequestDto model) + { + return Task.FromResult(GetForecast(model)); + } + + public IEnumerable GetForecast(ForecastRequestDto model) + { + switch (model.PostalCode) { - return Task.FromResult(GetForecast(model)); + case "NotFound": + throw new ForecastNotFoundException(); + case "Conflict": + throw new ForecastConflictException(); } - public IEnumerable GetForecast(ForecastRequestDto model) + // validate model + if (model.PostalCode.Length > 10) { - switch (model.PostalCode) + throw new ForecastRequestInvalidException(new Dictionary() { - case "NotFound": - throw new ForecastNotFoundException(); - case "Conflict": - throw new ForecastConflictException(); - } + { nameof(model.PostalCode), _stringLocalizer["PostalCode cannot exceed 10 characters."].Value } + }); + } - // validate model - if (model.PostalCode.Length > 10) + // test single result value + if (model.PostalCode == "55555") + { + return new List { - throw new ForecastRequestInvalidException(new Dictionary() + new WeatherForecast { - { nameof(model.PostalCode), _stringLocalizer["PostalCode cannot exceed 10 characters."].Value } - }); - } + Date = DateTime.Now, + TemperatureC = 0, + Summary = Summaries[0] + } + }; + } - // test single result value - if (model.PostalCode == "55555") + var rng = new Random(); + return new List(Enumerable.Range(1, 5) + .Select(index => new WeatherForecast { - return new List - { - new WeatherForecast - { - Date = DateTime.Now, - TemperatureC = 0, - Summary = Summaries[0] - } - }; - } - - var rng = new Random(); - return new List(Enumerable.Range(1, 5) - .Select(index => new WeatherForecast - { - Date = DateTime.Now.AddDays(index), - TemperatureC = rng.Next(-20, 55), - Summary = Summaries[rng.Next(Summaries.Length)] - }) - .ToArray()); - } + Date = DateTime.Now.AddDays(index), + TemperatureC = rng.Next(-20, 55), + Summary = Summaries[rng.Next(Summaries.Length)] + }) + .ToArray()); } } diff --git a/sample/Ardalis.Result.Sample.UnitTests/ServiceTests/BadResultService_ReturnResultWithError.cs b/sample/Ardalis.Result.Sample.UnitTests/ServiceTests/BadResultService_ReturnResultWithError.cs new file mode 100644 index 0000000..c1f7c62 --- /dev/null +++ b/sample/Ardalis.Result.Sample.UnitTests/ServiceTests/BadResultService_ReturnResultWithError.cs @@ -0,0 +1,20 @@ +using System.Linq; +using Ardalis.Result.Sample.Core.Services; +using FluentAssertions; +using Xunit; + +namespace Ardalis.Result.Sample.UnitTests.ServiceTests; + +public class BadResultService_ReturnResultWithError +{ + [Fact] + public void ReturnsErrorResultGivenMessage() + { + var service = new BadResultService(); + + var result = service.ReturnErrorWithMessage("Some error message"); + + result.Status.Should().Be(ResultStatus.Error); + result.Errors.Single().Should().Be("Some error message"); + } +} diff --git a/src/Ardalis.Result/Result.Void.cs b/src/Ardalis.Result/Result.Void.cs index c756864..8486536 100644 --- a/src/Ardalis.Result/Result.Void.cs +++ b/src/Ardalis.Result/Result.Void.cs @@ -64,6 +64,18 @@ public new static Result Error(ErrorList error = null) }; } + /// + /// Represents an error that occurred during the execution of the service. + /// A single error message may be provided and will be exposed via the Errors property. + /// + /// + /// + public static Result Error(string errorMessage) + { + return new Result(ResultStatus.Error) { Errors = new[] { errorMessage } }; + } + + /// /// Represents the validation error that prevents the underlying service from completing. /// diff --git a/tests/Ardalis.Result.UnitTests/ResultImplicitOperators.cs b/tests/Ardalis.Result.UnitTests/ResultImplicitOperators.cs index 20b842f..ed0e2a1 100644 --- a/tests/Ardalis.Result.UnitTests/ResultImplicitOperators.cs +++ b/tests/Ardalis.Result.UnitTests/ResultImplicitOperators.cs @@ -1,3 +1,4 @@ +using System.Linq; using Xunit; namespace Ardalis.Result.UnitTests; @@ -83,6 +84,17 @@ public void ConvertToNullObjectValue() Assert.Equal(expectedNullObject, result); } + [Fact] + public void ConvertResultResultToResult() + { + var result = Result.Error(expectedString); + + Result convertedResult = result; + + Assert.NotNull(convertedResult); + Assert.Equal(expectedString, convertedResult.Errors.First()); + } + public Result DoBusinessOperationExample(T testValue) => testValue; public T GetValueForResultExample(Result testResult) => testResult;