From 17c8be9e7ce29236e8390ff5f20c4af3f06cb712 Mon Sep 17 00:00:00 2001 From: Zbigniew Prasak Date: Sun, 17 Nov 2024 12:45:44 +0100 Subject: [PATCH 01/13] Version bump to 3.0.0-alpha.0 --- .editorconfig | 3 +++ src/ErrorOr.csproj | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.editorconfig b/.editorconfig index 04559f5..776b881 100644 --- a/.editorconfig +++ b/.editorconfig @@ -70,3 +70,6 @@ dotnet_diagnostic.SA1642.severity = none # SA1516: Elements should be separated by blank line dotnet_diagnostic.SA1516.severity = none + +[*.csproj] +indent_size = 2 diff --git a/src/ErrorOr.csproj b/src/ErrorOr.csproj index 55ea443..a6a0341 100644 --- a/src/ErrorOr.csproj +++ b/src/ErrorOr.csproj @@ -7,7 +7,8 @@ ErrorOr - 2.0.1 + 3.0.0 + alpha.0 Amichai Mantinband icon-square.png Result,Results,ErrorOr,Error,Handling From 990205202cfb76129bfd77aa749fbe7b7d880898 Mon Sep 17 00:00:00 2001 From: Zbigniew Prasak Date: Sun, 17 Nov 2024 13:19:58 +0100 Subject: [PATCH 02/13] Added FailIf overloads to CHANGELOG --- CHANGELOG.md | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ecd515..997aff2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -55,3 +55,58 @@ errorOr.FailIf(x => x > 0, Error.Failure()); -public static async Task> ThenAsync(this Task> errorOr, Func action) +public static async Task> ThenDoAsync(this Task> errorOr, Func action) ``` + +## [3.0.0-alpha.0] - to be released + +### Added + +- (#94, #95) Added missing async versions of `FailIf` methods (thanks [@MGREMY](https://github.com/MGREMY)!) + +```cs +public async Task> FailIfAsync(Func> onValue, Error error) +``` + +```cs +public static async Task> FailIf( + this Task> errorOr, + Func onValue, + Error error) +``` + +```cs +public static async Task> FailIfAsync( + this Task> errorOr, + Func> onValue, + Error error) +``` + +- (#109, #111) Added `FailIf` method overloads that allow to use value in error definition using `Func` error builder (thanks [@ahmtsen](https://github.com/ahmtsen)!) + +```cs +public ErrorOr FailIf(Func onValue, Func errorBuilder) +``` + +```cs +public async Task> FailIfAsync(Func> onValue, Func> errorBuilder) +``` + +```cs +public static async Task> FailIf( + this Task> errorOr, + Func onValue, + Func errorBuilder) +``` + +```cs +public static async Task> FailIfAsync( + this Task> errorOr, + Func> onValue, + Func> errorBuilder) +``` + +Value can now be used to build the error: + +```cs +ErrorOr result = errorOrInt + .FailIf(num => num > 3, (num) => Error.Failure(description: $"{num} is greater than 3")); +``` From 2c07122a165e499ed8026fcc03e2fd66a60eee25 Mon Sep 17 00:00:00 2001 From: Zbigniew Prasak Date: Sun, 17 Nov 2024 14:30:50 +0100 Subject: [PATCH 03/13] Added turing into ValueObject to CHANGELOG --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 997aff2..9c2dd5a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -110,3 +110,9 @@ Value can now be used to build the error: ErrorOr result = errorOrInt .FailIf(num => num > 3, (num) => Error.Failure(description: $"{num} is greater than 3")); ``` + +### Fixed + +- (#85, #97) `ErrorOr` turned into Value Object by reimplementing `Equals` and `GetHashCode` methods + +New dependency was introduced to [Microsoft.Bcl.HashCode](https://www.nuget.org/packages/Microsoft.Bcl.HashCode) and development dependency was introduced to [Nullable](https://www.nuget.org/packages/Nullable) From e51d368e98ae0e4aa27aaa42910068858fc22452 Mon Sep 17 00:00:00 2001 From: Zbigniew Prasak Date: Sun, 17 Nov 2024 14:36:15 +0100 Subject: [PATCH 04/13] .NET version support change added to CHANGELOG --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c2dd5a..f90a5cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,6 +58,10 @@ errorOr.FailIf(x => x > 0, Error.Failure()); ## [3.0.0-alpha.0] - to be released +### Breaking Changes + +- (#104) Support for .NET 6 was removed + ### Added - (#94, #95) Added missing async versions of `FailIf` methods (thanks [@MGREMY](https://github.com/MGREMY)!) @@ -80,6 +84,8 @@ public static async Task> FailIfAsync( Error error) ``` +- (#104) Support for .NET 8 was added + - (#109, #111) Added `FailIf` method overloads that allow to use value in error definition using `Func` error builder (thanks [@ahmtsen](https://github.com/ahmtsen)!) ```cs From b6f297713a494280c56a29884b388c4f97b4bc88 Mon Sep 17 00:00:00 2001 From: Zbigniew Prasak Date: Sun, 17 Nov 2024 14:39:07 +0100 Subject: [PATCH 05/13] Memory optimizations added to CHANGELOG --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f90a5cd..363db83 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -122,3 +122,7 @@ ErrorOr result = errorOrInt - (#85, #97) `ErrorOr` turned into Value Object by reimplementing `Equals` and `GetHashCode` methods New dependency was introduced to [Microsoft.Bcl.HashCode](https://www.nuget.org/packages/Microsoft.Bcl.HashCode) and development dependency was introduced to [Nullable](https://www.nuget.org/packages/Nullable) + +### Optimized + +- (#98, #99) Memory consumption optimized by moving static empty errors lists from generic struct into non-generic class From 2c042b428ba592db587ea095a1f114936d47341d Mon Sep 17 00:00:00 2001 From: Zbigniew Prasak Date: Sun, 17 Nov 2024 14:46:31 +0100 Subject: [PATCH 06/13] Errors to exception added to CHANGELOG --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 363db83..8d4e1de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -62,6 +62,14 @@ errorOr.FailIf(x => x > 0, Error.Failure()); - (#104) Support for .NET 6 was removed +- (#105) Invalid use of library now throws exception instead of return errors + + Following actions now throws `InvalidOperationException`: + + 1. Default `ErrorOr` constructor invocation. + 2. Accessing `ErrorOr.Errors` and `ErrorOr.FirstError` on success result. + 3. Accessing `ErrorOr.Value` on result with errors. + ### Added - (#94, #95) Added missing async versions of `FailIf` methods (thanks [@MGREMY](https://github.com/MGREMY)!) From 06de3e2e033b687c6b16a36a880dbd041fbfff1b Mon Sep 17 00:00:00 2001 From: Zbigniew Prasak Date: Sun, 17 Nov 2024 15:32:18 +0100 Subject: [PATCH 07/13] Indents added to CHANGELOG --- CHANGELOG.md | 82 ++++++++++++++++++++++++++-------------------------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d4e1de..89f1416 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -74,62 +74,62 @@ errorOr.FailIf(x => x > 0, Error.Failure()); - (#94, #95) Added missing async versions of `FailIf` methods (thanks [@MGREMY](https://github.com/MGREMY)!) -```cs -public async Task> FailIfAsync(Func> onValue, Error error) -``` - -```cs -public static async Task> FailIf( - this Task> errorOr, - Func onValue, - Error error) -``` - -```cs -public static async Task> FailIfAsync( - this Task> errorOr, - Func> onValue, - Error error) -``` + ```cs + public async Task> FailIfAsync(Func> onValue, Error error) + ``` + + ```cs + public static async Task> FailIf( + this Task> errorOr, + Func onValue, + Error error) + ``` + + ```cs + public static async Task> FailIfAsync( + this Task> errorOr, + Func> onValue, + Error error) + ``` - (#104) Support for .NET 8 was added - (#109, #111) Added `FailIf` method overloads that allow to use value in error definition using `Func` error builder (thanks [@ahmtsen](https://github.com/ahmtsen)!) -```cs -public ErrorOr FailIf(Func onValue, Func errorBuilder) -``` + ```cs + public ErrorOr FailIf(Func onValue, Func errorBuilder) + ``` -```cs -public async Task> FailIfAsync(Func> onValue, Func> errorBuilder) -``` + ```cs + public async Task> FailIfAsync(Func> onValue, Func> errorBuilder) + ``` -```cs -public static async Task> FailIf( - this Task> errorOr, - Func onValue, - Func errorBuilder) -``` + ```cs + public static async Task> FailIf( + this Task> errorOr, + Func onValue, + Func errorBuilder) + ``` -```cs -public static async Task> FailIfAsync( - this Task> errorOr, - Func> onValue, - Func> errorBuilder) -``` + ```cs + public static async Task> FailIfAsync( + this Task> errorOr, + Func> onValue, + Func> errorBuilder) + ``` -Value can now be used to build the error: + Value can now be used to build the error: -```cs -ErrorOr result = errorOrInt - .FailIf(num => num > 3, (num) => Error.Failure(description: $"{num} is greater than 3")); -``` + ```cs + ErrorOr result = errorOrInt + .FailIf(num => num > 3, (num) => Error.Failure(description: $"{num} is greater than 3")); + ``` ### Fixed - (#85, #97) `ErrorOr` turned into Value Object by reimplementing `Equals` and `GetHashCode` methods -New dependency was introduced to [Microsoft.Bcl.HashCode](https://www.nuget.org/packages/Microsoft.Bcl.HashCode) and development dependency was introduced to [Nullable](https://www.nuget.org/packages/Nullable) + New dependency was introduced to [Microsoft.Bcl.HashCode](https://www.nuget.org/packages/Microsoft.Bcl.HashCode) and development dependency was introduced to [Nullable](https://www.nuget.org/packages/Nullable) ### Optimized From 24f054a432dc579a2ed33394a66b69a28ebc37c2 Mon Sep 17 00:00:00 2001 From: Zbigniew Prasak Date: Sun, 17 Nov 2024 15:32:57 +0100 Subject: [PATCH 08/13] Indents to previous versions added to CHANGELOG --- CHANGELOG.md | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 89f1416..a10c715 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,40 +21,40 @@ All notable changes to this project are documented in this file. - `FailIf` -```csharp -public ErrorOr FailIf(Func onValue, Error error) -``` + ```csharp + public ErrorOr FailIf(Func onValue, Error error) + ``` -```csharp -ErrorOr errorOr = 1; -errorOr.FailIf(x => x > 0, Error.Failure()); -``` + ```csharp + ErrorOr errorOr = 1; + errorOr.FailIf(x => x > 0, Error.Failure()); + ``` ### Breaking Changes - `Then` that receives an action is now called `ThenDo` -```diff --public ErrorOr Then(Action action) -+public ErrorOr ThenDo(Action action) -``` + ```diff + -public ErrorOr Then(Action action) + +public ErrorOr ThenDo(Action action) + ``` -```diff --public static async Task> Then(this Task> errorOr, Action action) -+public static async Task> ThenDo(this Task> errorOr, Action action) -``` + ```diff + -public static async Task> Then(this Task> errorOr, Action action) + +public static async Task> ThenDo(this Task> errorOr, Action action) + ``` - `ThenAsync` that receives an action is now called `ThenDoAsync` -```diff --public async Task> ThenAsync(Func action) -+public async Task> ThenDoAsync(Func action) -``` + ```diff + -public async Task> ThenAsync(Func action) + +public async Task> ThenDoAsync(Func action) + ``` -```diff --public static async Task> ThenAsync(this Task> errorOr, Func action) -+public static async Task> ThenDoAsync(this Task> errorOr, Func action) -``` + ```diff + -public static async Task> ThenAsync(this Task> errorOr, Func action) + +public static async Task> ThenDoAsync(this Task> errorOr, Func action) + ``` ## [3.0.0-alpha.0] - to be released From 8e64fc7090e8a4e20fe177183016148c064c69ae Mon Sep 17 00:00:00 2001 From: Zbigniew Prasak Date: Sun, 17 Nov 2024 15:33:40 +0100 Subject: [PATCH 09/13] Version number 2.0.0 fixed to 2.0.1 in CHANGELOG --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a10c715..bade8c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,7 @@ All notable changes to this project are documented in this file. - `ToErrorOr` -## [2.0.0] - 2024-03-26 +## [2.0.1] - 2024-03-26 ### Added From 980a9734f804537dac2cf43a3edd47739b6bd4b0 Mon Sep 17 00:00:00 2001 From: Zbigniew Prasak Date: Sun, 17 Nov 2024 15:35:07 +0100 Subject: [PATCH 10/13] CHANGELOG reordered to backwards direction --- CHANGELOG.md | 122 +++++++++++++++++++++++++-------------------------- 1 file changed, 61 insertions(+), 61 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bade8c7..7e35aac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,67 +2,13 @@ All notable changes to this project are documented in this file. -## [1.10.0] - 2024-02-14 - -### Added - -- `ErrorType.Forbidden` -- README to NuGet package - -## [1.9.0] - 2024-01-06 - -### Added - -- `ToErrorOr` - -## [2.0.1] - 2024-03-26 - -### Added - -- `FailIf` - - ```csharp - public ErrorOr FailIf(Func onValue, Error error) - ``` - - ```csharp - ErrorOr errorOr = 1; - errorOr.FailIf(x => x > 0, Error.Failure()); - ``` - -### Breaking Changes - -- `Then` that receives an action is now called `ThenDo` - - ```diff - -public ErrorOr Then(Action action) - +public ErrorOr ThenDo(Action action) - ``` - - ```diff - -public static async Task> Then(this Task> errorOr, Action action) - +public static async Task> ThenDo(this Task> errorOr, Action action) - ``` - -- `ThenAsync` that receives an action is now called `ThenDoAsync` - - ```diff - -public async Task> ThenAsync(Func action) - +public async Task> ThenDoAsync(Func action) - ``` - - ```diff - -public static async Task> ThenAsync(this Task> errorOr, Func action) - +public static async Task> ThenDoAsync(this Task> errorOr, Func action) - ``` - ## [3.0.0-alpha.0] - to be released ### Breaking Changes -- (#104) Support for .NET 6 was removed +- [#104](https://github.com/amantinband/error-or/pull/104) Support for .NET 6 was removed -- (#105) Invalid use of library now throws exception instead of return errors +- [#105](https://github.com/amantinband/error-or/pull/105) Invalid use of library now throws exception instead of return errors Following actions now throws `InvalidOperationException`: @@ -72,7 +18,7 @@ All notable changes to this project are documented in this file. ### Added -- (#94, #95) Added missing async versions of `FailIf` methods (thanks [@MGREMY](https://github.com/MGREMY)!) +- [#94](https://github.com/amantinband/error-or/issues/94), [#95](https://github.com/amantinband/error-or/pull/95) Added missing async versions of `FailIf` methods (thanks [@MGREMY](https://github.com/MGREMY)!) ```cs public async Task> FailIfAsync(Func> onValue, Error error) @@ -92,9 +38,9 @@ All notable changes to this project are documented in this file. Error error) ``` -- (#104) Support for .NET 8 was added +- [#104](https://github.com/amantinband/error-or/pull/104) Support for .NET 8 was added -- (#109, #111) Added `FailIf` method overloads that allow to use value in error definition using `Func` error builder (thanks [@ahmtsen](https://github.com/ahmtsen)!) +- [#109](https://github.com/amantinband/error-or/issues/109), [#111](https://github.com/amantinband/error-or/pull/111) Added `FailIf` method overloads that allow to use value in error definition using `Func` error builder (thanks [@ahmtsen](https://github.com/ahmtsen)!) ```cs public ErrorOr FailIf(Func onValue, Func errorBuilder) @@ -127,10 +73,64 @@ All notable changes to this project are documented in this file. ### Fixed -- (#85, #97) `ErrorOr` turned into Value Object by reimplementing `Equals` and `GetHashCode` methods +- [#85](https://github.com/amantinband/error-or/issues/85), [#97](https://github.com/amantinband/error-or/pull/97) `ErrorOr` turned into Value Object by reimplementing `Equals` and `GetHashCode` methods New dependency was introduced to [Microsoft.Bcl.HashCode](https://www.nuget.org/packages/Microsoft.Bcl.HashCode) and development dependency was introduced to [Nullable](https://www.nuget.org/packages/Nullable) ### Optimized -- (#98, #99) Memory consumption optimized by moving static empty errors lists from generic struct into non-generic class +- [#98](https://github.com/amantinband/error-or/issues/98), [#99](https://github.com/amantinband/error-or/pull/99) Memory consumption optimized by moving static empty errors lists from generic struct into non-generic class + +## [2.0.1] - 2024-03-26 + +### Breaking Changes + +- `Then` that receives an action is now called `ThenDo` + + ```diff + -public ErrorOr Then(Action action) + +public ErrorOr ThenDo(Action action) + ``` + + ```diff + -public static async Task> Then(this Task> errorOr, Action action) + +public static async Task> ThenDo(this Task> errorOr, Action action) + ``` + +- `ThenAsync` that receives an action is now called `ThenDoAsync` + + ```diff + -public async Task> ThenAsync(Func action) + +public async Task> ThenDoAsync(Func action) + ``` + + ```diff + -public static async Task> ThenAsync(this Task> errorOr, Func action) + +public static async Task> ThenDoAsync(this Task> errorOr, Func action) + ``` + +### Added + +- `FailIf` + + ```csharp + public ErrorOr FailIf(Func onValue, Error error) + ``` + + ```csharp + ErrorOr errorOr = 1; + errorOr.FailIf(x => x > 0, Error.Failure()); + ``` + +## [1.10.0] - 2024-02-14 + +### Added + +- `ErrorType.Forbidden` +- README to NuGet package + +## [1.9.0] - 2024-01-06 + +### Added + +- `ToErrorOr` From 220d00ce8133ff8f61fa3393842c7d0a8dc9b175 Mon Sep 17 00:00:00 2001 From: Zbigniew Prasak Date: Sun, 17 Nov 2024 16:15:47 +0100 Subject: [PATCH 11/13] Acknowledgements removed --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e35aac..5a41548 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,7 @@ All notable changes to this project are documented in this file. ### Added -- [#94](https://github.com/amantinband/error-or/issues/94), [#95](https://github.com/amantinband/error-or/pull/95) Added missing async versions of `FailIf` methods (thanks [@MGREMY](https://github.com/MGREMY)!) +- [#94](https://github.com/amantinband/error-or/issues/94), [#95](https://github.com/amantinband/error-or/pull/95) Added missing async versions of `FailIf` methods ```cs public async Task> FailIfAsync(Func> onValue, Error error) @@ -40,7 +40,7 @@ All notable changes to this project are documented in this file. - [#104](https://github.com/amantinband/error-or/pull/104) Support for .NET 8 was added -- [#109](https://github.com/amantinband/error-or/issues/109), [#111](https://github.com/amantinband/error-or/pull/111) Added `FailIf` method overloads that allow to use value in error definition using `Func` error builder (thanks [@ahmtsen](https://github.com/ahmtsen)!) +- [#109](https://github.com/amantinband/error-or/issues/109), [#111](https://github.com/amantinband/error-or/pull/111) Added `FailIf` method overloads that allow to use value in error definition using `Func` error builder ```cs public ErrorOr FailIf(Func onValue, Func errorBuilder) From cba25ff680246d9ea740d4cc644a8b371e6950a2 Mon Sep 17 00:00:00 2001 From: Zbigniew Prasak Date: Wed, 4 Dec 2024 23:24:54 +0100 Subject: [PATCH 12/13] Reverting .NET 6 support removal .NET 6 support removal from #104 reverted while maintaining .NET 8 support --- CHANGELOG.md | 2 -- src/ErrorOr.csproj | 2 +- tests/Tests.csproj | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a41548..beea430 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,8 +6,6 @@ All notable changes to this project are documented in this file. ### Breaking Changes -- [#104](https://github.com/amantinband/error-or/pull/104) Support for .NET 6 was removed - - [#105](https://github.com/amantinband/error-or/pull/105) Invalid use of library now throws exception instead of return errors Following actions now throws `InvalidOperationException`: diff --git a/src/ErrorOr.csproj b/src/ErrorOr.csproj index a6a0341..98390ed 100644 --- a/src/ErrorOr.csproj +++ b/src/ErrorOr.csproj @@ -1,6 +1,6 @@ - netstandard2.0;net8.0 + netstandard2.0;net6.0;net8.0 enable enable true diff --git a/tests/Tests.csproj b/tests/Tests.csproj index 8170f9a..594def7 100644 --- a/tests/Tests.csproj +++ b/tests/Tests.csproj @@ -1,7 +1,7 @@ - net8.0 + net6.0;net8.0 enable enable From f5abe22cf7e95c4e34fc43c30e84a6ce478c326f Mon Sep 17 00:00:00 2001 From: Zbigniew Prasak Date: Wed, 4 Dec 2024 23:36:03 +0100 Subject: [PATCH 13/13] Reverting exception throwing upon invalid usage Throwing exceptions upon invalid usage of library from #105 reverted. Behavior of following actions is now being restored: 1. Default `ErrorOr` constructor invocation. 2. Accessing `ErrorOr.Errors` and `ErrorOr.FirstError` on success result. 3. Accessing `ErrorOr.Value` on result with errors. --- CHANGELOG.md | 12 +---- src/ErrorOr.csproj | 2 +- src/ErrorOr/EmptyErrors.cs | 6 --- src/ErrorOr/ErrorOr.cs | 31 ++--------- src/Errors/KnownErrors.cs | 16 ++++++ tests/ErrorOr/ErrorOr.InstantiationTests.cs | 60 +++++++++------------ 6 files changed, 46 insertions(+), 81 deletions(-) delete mode 100644 src/ErrorOr/EmptyErrors.cs create mode 100644 src/Errors/KnownErrors.cs diff --git a/CHANGELOG.md b/CHANGELOG.md index beea430..c5d53b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,17 +2,7 @@ All notable changes to this project are documented in this file. -## [3.0.0-alpha.0] - to be released - -### Breaking Changes - -- [#105](https://github.com/amantinband/error-or/pull/105) Invalid use of library now throws exception instead of return errors - - Following actions now throws `InvalidOperationException`: - - 1. Default `ErrorOr` constructor invocation. - 2. Accessing `ErrorOr.Errors` and `ErrorOr.FirstError` on success result. - 3. Accessing `ErrorOr.Value` on result with errors. +## [2.1.0-alpha.0] - to be released ### Added diff --git a/src/ErrorOr.csproj b/src/ErrorOr.csproj index 98390ed..6a7420b 100644 --- a/src/ErrorOr.csproj +++ b/src/ErrorOr.csproj @@ -7,7 +7,7 @@ ErrorOr - 3.0.0 + 2.1.0 alpha.0 Amichai Mantinband icon-square.png diff --git a/src/ErrorOr/EmptyErrors.cs b/src/ErrorOr/EmptyErrors.cs deleted file mode 100644 index 7a79e64..0000000 --- a/src/ErrorOr/EmptyErrors.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace ErrorOr; - -internal static class EmptyErrors -{ - public static List Instance { get; } = []; -} diff --git a/src/ErrorOr/ErrorOr.cs b/src/ErrorOr/ErrorOr.cs index b958157..a473f6f 100644 --- a/src/ErrorOr/ErrorOr.cs +++ b/src/ErrorOr/ErrorOr.cs @@ -11,15 +11,6 @@ namespace ErrorOr; private readonly TValue? _value = default; private readonly List? _errors = null; - /// - /// Prevents a default struct from being created. - /// - /// Thrown when this method is called. - public ErrorOr() - { - throw new InvalidOperationException("Default construction of ErrorOr is invalid. Please use provided factory methods to instantiate."); - } - private ErrorOr(Error error) { _errors = [error]; @@ -62,42 +53,28 @@ private ErrorOr(TValue value) /// /// Gets the list of errors. If the state is not error, the list will contain a single error representing the state. /// - /// Thrown when no errors are present. - public List Errors => IsError ? _errors : throw new InvalidOperationException("The Errors property cannot be accessed when no errors have been recorded. Check IsError before accessing Errors."); + public List Errors => IsError ? _errors : KnownErrors.CachedNoErrorsList; /// /// Gets the list of errors. If the state is not error, the list will be empty. /// - public List ErrorsOrEmptyList => IsError ? _errors : EmptyErrors.Instance; + public List ErrorsOrEmptyList => IsError ? _errors : KnownErrors.CachedEmptyErrorsList; /// /// Gets the value. /// - /// Thrown when no value is present. - public TValue Value - { - get - { - if (IsError) - { - throw new InvalidOperationException("The Value property cannot be accessed when errors have been recorded. Check IsError before accessing Value."); - } - - return _value; - } - } + public TValue Value => _value!; /// /// Gets the first error. /// - /// Thrown when no errors are present. public Error FirstError { get { if (!IsError) { - throw new InvalidOperationException("The FirstError property cannot be accessed when no errors have been recorded. Check IsError before accessing FirstError."); + return KnownErrors.NoFirstError; } return _errors[0]; diff --git a/src/Errors/KnownErrors.cs b/src/Errors/KnownErrors.cs new file mode 100644 index 0000000..cfa7220 --- /dev/null +++ b/src/Errors/KnownErrors.cs @@ -0,0 +1,16 @@ +namespace ErrorOr; + +internal static class KnownErrors +{ + public static Error NoFirstError { get; } = Error.Unexpected( + code: "ErrorOr.NoFirstError", + description: "First error cannot be retrieved from a successful ErrorOr."); + + public static Error NoErrors { get; } = Error.Unexpected( + code: "ErrorOr.NoErrors", + description: "Error list cannot be retrieved from a successful ErrorOr."); + + public static List CachedNoErrorsList { get; } = new (1) { NoErrors }; + + public static List CachedEmptyErrorsList { get; } = new (0); +} diff --git a/tests/ErrorOr/ErrorOr.InstantiationTests.cs b/tests/ErrorOr/ErrorOr.InstantiationTests.cs index 77d17ca..4b91c0c 100644 --- a/tests/ErrorOr/ErrorOr.InstantiationTests.cs +++ b/tests/ErrorOr/ErrorOr.InstantiationTests.cs @@ -22,17 +22,17 @@ public void CreateFromFactory_WhenAccessingValue_ShouldReturnValue() } [Fact] - public void CreateFromFactory_WhenAccessingErrors_ShouldThrow() + public void CreateFromFactory_WhenAccessingErrors_ShouldReturnUnexpectedError() { // Arrange IEnumerable value = ["value"]; ErrorOr> errorOrPerson = ErrorOrFactory.From(value); // Act - Func> errors = () => errorOrPerson.Errors; + List errors = errorOrPerson.Errors; // Assert - errors.Should().ThrowExactly(); + errors.Should().ContainSingle().Which.Type.Should().Be(ErrorType.Unexpected); } [Fact] @@ -50,17 +50,17 @@ public void CreateFromFactory_WhenAccessingErrorsOrEmptyList_ShouldReturnEmptyLi } [Fact] - public void CreateFromFactory_WhenAccessingFirstError_ShouldThrow() + public void CreateFromFactory_WhenAccessingFirstError_ShouldReturnUnexpectedError() { // Arrange IEnumerable value = ["value"]; ErrorOr> errorOrPerson = ErrorOrFactory.From(value); // Act - Func action = () => errorOrPerson.FirstError; + Error firstError = errorOrPerson.FirstError; // Assert - action.Should().ThrowExactly(); + firstError.Type.Should().Be(ErrorType.Unexpected); } [Fact] @@ -78,17 +78,17 @@ public void CreateFromValue_WhenAccessingValue_ShouldReturnValue() } [Fact] - public void CreateFromValue_WhenAccessingErrors_ShouldThrow() + public void CreateFromValue_WhenAccessingErrors_ShouldReturnUnexpectedError() { // Arrange IEnumerable value = ["value"]; ErrorOr> errorOrPerson = ErrorOrFactory.From(value); // Act - Func> action = () => errorOrPerson.Errors; + List errors = errorOrPerson.Errors; // Assert - action.Should().ThrowExactly(); + errors.Should().ContainSingle().Which.Type.Should().Be(ErrorType.Unexpected); } [Fact] @@ -106,17 +106,17 @@ public void CreateFromValue_WhenAccessingErrorsOrEmptyList_ShouldReturnEmptyList } [Fact] - public void CreateFromValue_WhenAccessingFirstError_ShouldThrow() + public void CreateFromValue_WhenAccessingFirstError_ShouldReturnUnexpectedError() { // Arrange IEnumerable value = ["value"]; ErrorOr> errorOrPerson = ErrorOrFactory.From(value); // Act - Func action = () => errorOrPerson.FirstError; + Error firstError = errorOrPerson.FirstError; // Assert - action.Should().ThrowExactly(); + firstError.Type.Should().Be(ErrorType.Unexpected); } [Fact] @@ -144,18 +144,17 @@ public void CreateFromErrorList_WhenAccessingErrorsOrEmptyList_ShouldReturnError } [Fact] - public void CreateFromErrorList_WhenAccessingValue_ShouldThrowInvalidOperationException() + public void CreateFromErrorList_WhenAccessingValue_ShouldReturnDefault() { // Arrange List errors = new() { Error.Validation("User.Name", "Name is too short") }; ErrorOr errorOrPerson = ErrorOr.From(errors); // Act - var act = () => errorOrPerson.Value; + Person value = errorOrPerson.Value; // Assert - act.Should().Throw() - .And.Message.Should().Be("The Value property cannot be accessed when errors have been recorded. Check IsError before accessing Value."); + value.Should().Be(default); } [Fact] @@ -173,27 +172,27 @@ public void ImplicitCastResult_WhenAccessingResult_ShouldReturnValue() } [Fact] - public void ImplicitCastResult_WhenAccessingErrors_ShouldThrow() + public void ImplicitCastResult_WhenAccessingErrors_ShouldReturnUnexpectedError() { ErrorOr errorOrPerson = new Person("Amichai"); // Act - Func> action = () => errorOrPerson.Errors; + List errors = errorOrPerson.Errors; // Assert - action.Should().ThrowExactly(); + errors.Should().ContainSingle().Which.Type.Should().Be(ErrorType.Unexpected); } [Fact] - public void ImplicitCastResult_WhenAccessingFirstError_ShouldThrow() + public void ImplicitCastResult_WhenAccessingFirstError_ShouldReturnUnexpectedError() { ErrorOr errorOrPerson = new Person("Amichai"); // Act - Func action = () => errorOrPerson.FirstError; + Error firstError = errorOrPerson.FirstError; // Assert - action.Should().ThrowExactly(); + firstError.Type.Should().Be(ErrorType.Unexpected); } [Fact] @@ -248,17 +247,16 @@ public void ImplicitCastSingleError_WhenAccessingErrors_ShouldReturnErrorList() } [Fact] - public void ImplicitCastError_WhenAccessingValue_ShouldThrowInvalidOperationException() + public void ImplicitCastError_WhenAccessingValue_ShouldReturnDefault() { // Arrange ErrorOr errorOrPerson = Error.Validation("User.Name", "Name is too short"); // Act - var act = () => errorOrPerson.Value; + Person value = errorOrPerson.Value; // Assert - act.Should().Throw() - .And.Message.Should().Be("The Value property cannot be accessed when errors have been recorded. Check IsError before accessing Value."); + value.Should().Be(default); } [Fact] @@ -347,16 +345,6 @@ public void ImplicitCastErrorArray_WhenAccessingFirstError_ShouldReturnFirstErro errorOrPerson.FirstError.Should().Be(errors[0]); } - [Fact] - public void CreateErrorOr_WhenUsingEmptyConstructor_ShouldThrow() - { - // Act - Func> action = () => new ErrorOr(); - - // Assert - action.Should().ThrowExactly(); - } - [Fact] public void CreateErrorOr_WhenEmptyErrorsList_ShouldThrow() {