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

Draft: Migrate from Errors to Exceptions for invalid use of library #105

Merged
merged 13 commits into from
May 12, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Next Next commit
Migrate from Errors to Exceptions for invalid use of library
  • Loading branch information
amantinband committed May 9, 2024
commit 09e09ad7071c5a5d1c2c1f564f5c1f142c12ea19
135 changes: 69 additions & 66 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -1,66 +1,69 @@
root = true

[*]
indent_style = space
indent_size = 4
end_of_line = crlf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

# SA1615: Element return value should be documented.
dotnet_diagnostic.SA1615.severity = none

# SA1611: Element parameters must be documented.
dotnet_diagnostic.SA1611.severity = none

# SA1633: File must have header.
dotnet_diagnostic.SA1633.severity = none

# SA1633: Generic type parameters must be documented.
dotnet_diagnostic.SA1618.severity = none

# SA1133: Each attribute should be placed in its own set of square brackets.
dotnet_diagnostic.SA1133.severity = none

# SA1600: Elements must be documented.
dotnet_diagnostic.SA1600.severity = none

# SA1601: Partial elementes should be documented.
dotnet_diagnostic.SA1601.severity = none

# SA1313: Parameter names must begin with lower case letter.
dotnet_diagnostic.SA1313.severity = none

# SA1009: Closing parenthesis should be followed by a space.
dotnet_diagnostic.SA1009.severity = none

# SA1000: The keyword 'new' should be followed by a space.
dotnet_diagnostic.SA1000.severity = none

# SA1101: Prefix local calls with this.
dotnet_diagnostic.SA1101.severity = none

# SA1309: Field should not begin with an underscore.
dotnet_diagnostic.SA1309.severity = none

# SA1602: Enumeration items should be documented.
dotnet_diagnostic.SA1602.severity = none

# CS1591: Missing XML comment for publicly visible type or member.
dotnet_diagnostic.CS1591.severity = none

# SA1200: Using directive should appear within a namespace declaration.
dotnet_diagnostic.SA1200.severity = none

# IDE0008: Use explicit type
csharp_style_var_when_type_is_apparent = true

# IDE0130: Namespace does not match folder structure
dotnet_style_namespace_match_folder = false

# IDE0023: Use block body for operators
csharp_style_expression_bodied_operators = when_on_single_line

# IDE0130: Namespace does not match folder structure
dotnet_diagnostic.IDE0130.severity = none
root = true

[*]
indent_style = space
indent_size = 4
end_of_line = crlf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

# SA1615: Element return value should be documented.
dotnet_diagnostic.SA1615.severity = none

# SA1611: Element parameters must be documented.
dotnet_diagnostic.SA1611.severity = none

# SA1633: File must have header.
dotnet_diagnostic.SA1633.severity = none

# SA1633: Generic type parameters must be documented.
dotnet_diagnostic.SA1618.severity = none

# SA1133: Each attribute should be placed in its own set of square brackets.
dotnet_diagnostic.SA1133.severity = none

# SA1600: Elements must be documented.
dotnet_diagnostic.SA1600.severity = none

# SA1601: Partial elementes should be documented.
dotnet_diagnostic.SA1601.severity = none

# SA1313: Parameter names must begin with lower case letter.
dotnet_diagnostic.SA1313.severity = none

# SA1009: Closing parenthesis should be followed by a space.
dotnet_diagnostic.SA1009.severity = none

# SA1000: The keyword 'new' should be followed by a space.
dotnet_diagnostic.SA1000.severity = none

# SA1101: Prefix local calls with this.
dotnet_diagnostic.SA1101.severity = none

# SA1309: Field should not begin with an underscore.
dotnet_diagnostic.SA1309.severity = none

# SA1602: Enumeration items should be documented.
dotnet_diagnostic.SA1602.severity = none

# CS1591: Missing XML comment for publicly visible type or member.
dotnet_diagnostic.CS1591.severity = none

# SA1200: Using directive should appear within a namespace declaration.
dotnet_diagnostic.SA1200.severity = none

# IDE0008: Use explicit type
csharp_style_var_when_type_is_apparent = true

# IDE0130: Namespace does not match folder structure
dotnet_style_namespace_match_folder = false

# IDE0023: Use block body for operators
csharp_style_expression_bodied_operators = when_on_single_line

# IDE0130: Namespace does not match folder structure
dotnet_diagnostic.IDE0130.severity = none

# SA1642: Constructor summary documentation should begin with standard text
dotnet_diagnostic.SA1642.severity = none
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ public static implicit operator ErrorOr<TValue>(Error error)
/// </summary>
public static implicit operator ErrorOr<TValue>(List<Error> errors)
{
if (errors.Count == 0)
{
throw new InvalidOperationException("Cannot create an ErrorOr<TValue> from an empty list of errors. Provide at least one error.");
}

return new ErrorOr<TValue>(errors);
}

Expand All @@ -34,6 +39,11 @@ public static implicit operator ErrorOr<TValue>(List<Error> errors)
/// </summary>
public static implicit operator ErrorOr<TValue>(Error[] errors)
{
if (errors.Length == 0)
{
throw new InvalidOperationException("Cannot create an ErrorOr<TValue> from an empty list of errors. Provide at least one error.");
}

return new ErrorOr<TValue>(errors.ToList());
}
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
8 changes: 8 additions & 0 deletions src/ErrorOr.cs → src/ErrorOr/ErrorOr.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@ namespace ErrorOr;
/// </summary>
public readonly partial record struct ErrorOr<TValue> : IErrorOr<TValue>
{
/// <summary>
/// Prevents a default <see cref="ErrorOr"/> struct from being created.
/// </summary>
public ErrorOr()
{
throw new InvalidOperationException("Default construction of ErrorOr<TValue> is invalid. Please use provided factory methods to instantiate.");
}

private readonly TValue? _value = default;
private readonly List<Error>? _errors = null;

Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ namespace Tests;
using ErrorOr;
using FluentAssertions;

public class ErrorOrTests
public class ErrorOrInstantiationTests
{
private record Person(string Name);

Expand Down Expand Up @@ -344,4 +344,36 @@ public void ImplicitCastErrorArray_WhenAccessingFirstError_ShouldReturnFirstErro
errorOrPerson.IsError.Should().BeTrue();
errorOrPerson.FirstError.Should().Be(errors[0]);
}

[Fact]
public void CreateErrorOr_WhenUsingEmptyConstructor_ShouldThrow()
{
// Act
#pragma warning disable SA1129 // Do not use default value type constructor
Func<ErrorOr<int>> errorOrInt = () => new ErrorOr<int>();
#pragma warning restore SA1129 // Do not use default value type constructor

// Assert
errorOrInt.Should().ThrowExactly<InvalidOperationException>();
}

[Fact]
public void CreateErrorOr_WhenEmptyErrorsList_ShouldThrow()
{
// Act
Func<ErrorOr<int>> errorOrInt = () => new List<Error>();

// Assert
errorOrInt.Should().ThrowExactly<InvalidOperationException>();
}

[Fact]
public void CreateErrorOr_WhenEmptyErrorsArray_ShouldThrow()
{
// Act
Func<ErrorOr<int>> errorOrInt = () => Array.Empty<Error>();

// Assert
errorOrInt.Should().ThrowExactly<InvalidOperationException>();
}
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading