Skip to content

Commit

Permalink
Refactor HTTP status code handling
Browse files Browse the repository at this point in the history
  • Loading branch information
marcominerva committed Jun 17, 2024
1 parent a561871 commit eae25e0
Show file tree
Hide file tree
Showing 11 changed files with 39 additions and 29 deletions.
4 changes: 2 additions & 2 deletions samples/Controllers/OperationResults.Sample/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@
// for the Operation Results of our Business Logic methods.
options.StatusCodesMapping.Add(CustomFailureReasons.NotAvailable, StatusCodes.Status501NotImplemented);
// If you just want to directly use HTTP status codes as failure reasons, set the following property to true.
// If you just want to directly use HTTP status codes as failure reasons, set the following property to false.
// In this way, the code you use with Result.Fail() will be used as response status code with no further mapping.
// options.UseHttpStatusCodes = true;
// options.MapStatusCodes = false;
},
//updateModelStateResponseFactory: true);
// Passing a validation error default message or a validation error message provider automatically update the ModelStateResponseFactory.
Expand Down
4 changes: 2 additions & 2 deletions samples/MinimalApis/OperationResults.Sample/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@
// for the Operation Results of our Business Logic methods.
options.StatusCodesMapping.Add(CustomFailureReasons.NotAvailable, StatusCodes.Status501NotImplemented);
// If you just want to directly use HTTP status codes as failure reasons, set the following property to true.
// If you just want to directly use HTTP status codes as failure reasons, set the following property to false.
// In this way, the code you use with Result.Fail() will be used as response status code with no further mapping.
//options.UseHttpStatusCodes = true;
options.MapStatusCodes = false;
});

builder.Services.AddEndpointsApiExplorer();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@

public static class CustomFailureReasons
{
public const int NotAvailable = 1001;
public const int NotAvailable = FailureReasons.GenericError + 1;
}
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public static IResult ToResponse<T>(this Result<T> result, HttpContext httpConte
private static IResult Problem(HttpContext httpContext, int failureReason, object? content = null, string? title = null, string? detail = null, IEnumerable<ValidationError>? validationErrors = null)
{
var options = httpContext.RequestServices.GetService<OperationResultOptions>() ?? new OperationResultOptions();
var statusCode = options.UseHttpStatusCodes ? failureReason : options.GetStatusCode(failureReason);
var statusCode = options.MapStatusCodes ? options.GetStatusCode(failureReason) : failureReason;

if (content is not null)
{
Expand Down
23 changes: 14 additions & 9 deletions src/OperationResults.AspNetCore.Http/OperationResultOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,33 @@ namespace OperationResults.AspNetCore.Http;

public class OperationResultOptions
{
public ErrorResponseFormat ErrorResponseFormat { get; set; }
public ErrorResponseFormat ErrorResponseFormat { get; set; } = ErrorResponseFormat.Default;

public Dictionary<int, int> StatusCodesMapping { get; }

public bool UseHttpStatusCodes { get; set; }
public bool MapStatusCodes { get; set; } = true;

public UnmappedFailureReasonBehavior UnmappedFailureReasonBehavior { get; set; }
public UnmappedFailureReasonBehavior UnmappedFailureReasonBehavior { get; set; } = UnmappedFailureReasonBehavior.UseDefaultStatusCode;

public int UnmappedFailureReasonStatusCode { get; set; } = StatusCodes.Status500InternalServerError;
public int UnmappedFailureReasonStatusCode { get; set; } = StatusCodes.Status501NotImplemented;

public OperationResultOptions()
{
StatusCodesMapping = new Dictionary<int, int>
{
[FailureReasons.None] = StatusCodes.Status200OK,
[FailureReasons.ItemNotFound] = StatusCodes.Status404NotFound,
[FailureReasons.Forbidden] = StatusCodes.Status403Forbidden,
[FailureReasons.DatabaseError] = StatusCodes.Status500InternalServerError,
[FailureReasons.ClientError] = StatusCodes.Status400BadRequest,
[FailureReasons.InvalidFile] = StatusCodes.Status415UnsupportedMediaType,
[FailureReasons.Conflict] = StatusCodes.Status409Conflict,
[FailureReasons.Unauthorized] = StatusCodes.Status401Unauthorized,
[FailureReasons.Forbidden] = StatusCodes.Status403Forbidden,
[FailureReasons.ItemNotFound] = StatusCodes.Status404NotFound,
[FailureReasons.InvalidRequest] = StatusCodes.Status406NotAcceptable,
[FailureReasons.Timeout] = StatusCodes.Status408RequestTimeout,
[FailureReasons.Conflict] = StatusCodes.Status409Conflict,
[FailureReasons.InvalidFile] = StatusCodes.Status415UnsupportedMediaType,
[FailureReasons.InvalidContent] = StatusCodes.Status422UnprocessableEntity,
[FailureReasons.DatabaseError] = StatusCodes.Status500InternalServerError,
[FailureReasons.NetworkError] = StatusCodes.Status500InternalServerError,
[FailureReasons.ServiceUnavailable] = StatusCodes.Status503ServiceUnavailable,
[FailureReasons.GenericError] = StatusCodes.Status500InternalServerError
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="OperationResultTools" Version="1.0.25" />
<PackageReference Include="OperationResultTools" Version="1.0.26" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

public enum UnmappedFailureReasonBehavior
{
UseFailureReason,
UseDefaultStatusCode,
UseFailureReason
}
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public static IActionResult ToResponse<T>(this Result<T> result, HttpContext htt
private static IActionResult Problem(HttpContext httpContext, int failureReason, object? content = null, string? title = null, string? detail = null, IEnumerable<ValidationError>? validationErrors = null)
{
var options = httpContext.RequestServices.GetService<OperationResultOptions>() ?? new OperationResultOptions();
var statusCode = options.UseHttpStatusCodes ? failureReason : options.GetStatusCode(failureReason);
var statusCode = options.MapStatusCodes ? options.GetStatusCode(failureReason) : failureReason;

if (content is not null)
{
Expand Down
23 changes: 14 additions & 9 deletions src/OperationResults.AspNetCore/OperationResultOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,33 @@ namespace OperationResults.AspNetCore;

public class OperationResultOptions
{
public ErrorResponseFormat ErrorResponseFormat { get; set; }
public ErrorResponseFormat ErrorResponseFormat { get; set; } = ErrorResponseFormat.Default;

public Dictionary<int, int> StatusCodesMapping { get; }

public bool UseHttpStatusCodes { get; set; }
public bool MapStatusCodes { get; set; } = true;

public UnmappedFailureReasonBehavior UnmappedFailureReasonBehavior { get; set; }
public UnmappedFailureReasonBehavior UnmappedFailureReasonBehavior { get; set; } = UnmappedFailureReasonBehavior.UseDefaultStatusCode;

public int UnmappedFailureReasonStatusCode { get; set; } = StatusCodes.Status500InternalServerError;
public int UnmappedFailureReasonStatusCode { get; set; } = StatusCodes.Status501NotImplemented;

public OperationResultOptions()
{
StatusCodesMapping = new Dictionary<int, int>
{
[FailureReasons.None] = StatusCodes.Status200OK,
[FailureReasons.ItemNotFound] = StatusCodes.Status404NotFound,
[FailureReasons.Forbidden] = StatusCodes.Status403Forbidden,
[FailureReasons.DatabaseError] = StatusCodes.Status500InternalServerError,
[FailureReasons.ClientError] = StatusCodes.Status400BadRequest,
[FailureReasons.InvalidFile] = StatusCodes.Status415UnsupportedMediaType,
[FailureReasons.Conflict] = StatusCodes.Status409Conflict,
[FailureReasons.Unauthorized] = StatusCodes.Status401Unauthorized,
[FailureReasons.Forbidden] = StatusCodes.Status403Forbidden,
[FailureReasons.ItemNotFound] = StatusCodes.Status404NotFound,
[FailureReasons.InvalidRequest] = StatusCodes.Status406NotAcceptable,
[FailureReasons.Timeout] = StatusCodes.Status408RequestTimeout,
[FailureReasons.Conflict] = StatusCodes.Status409Conflict,
[FailureReasons.InvalidFile] = StatusCodes.Status415UnsupportedMediaType,
[FailureReasons.InvalidContent] = StatusCodes.Status422UnprocessableEntity,
[FailureReasons.DatabaseError] = StatusCodes.Status500InternalServerError,
[FailureReasons.NetworkError] = StatusCodes.Status500InternalServerError,
[FailureReasons.ServiceUnavailable] = StatusCodes.Status503ServiceUnavailable,
[FailureReasons.GenericError] = StatusCodes.Status500InternalServerError
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="OperationResultTools" Version="1.0.25" />
<PackageReference Include="OperationResultTools" Version="1.0.26" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

public enum UnmappedFailureReasonBehavior
{
UseFailureReason,
UseDefaultStatusCode,
UseFailureReason
}

0 comments on commit eae25e0

Please sign in to comment.