Refactor: Rename DocumentOperator to DocumentService
Updated project and solution files to rename and restructure `DocumentOperator` to `DocumentService`. Modified project references in `DocumentService.API.csproj`, `DocumentService.Application.csproj`, and `DocumentService.Infrastructure.csproj` to reflect the new naming convention. Updated `DocumentService.sln` to remove old project references, add new ones, and adjust configuration and nested project mappings accordingly. This change aligns the project structure with the new naming convention.
This commit is contained in:
109
DocumentService.API/Middleware/ExceptionHandlingMiddleware.cs
Normal file
109
DocumentService.API/Middleware/ExceptionHandlingMiddleware.cs
Normal file
@@ -0,0 +1,109 @@
|
||||
using DocumentService.Domain.Common.Exceptions;
|
||||
using FluentValidation;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Net;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace DocumentService.API.Middleware;
|
||||
|
||||
/// <summary>
|
||||
/// Central exception handling middleware
|
||||
/// Maps exceptions to HTTP status codes and RFC 7807 Problem Details
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Initializes a new instance of the <see cref="ExceptionHandlingMiddleware"/> class.
|
||||
/// </remarks>
|
||||
/// <param name="Next">The next middleware in the pipeline.</param>
|
||||
public class ExceptionHandlingMiddleware(RequestDelegate Next)
|
||||
{
|
||||
private static readonly JsonSerializerOptions ProbDetailsJsonOpt = new()
|
||||
{
|
||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the middleware to handle incoming HTTP requests and catch exceptions.
|
||||
/// </summary>
|
||||
/// <param name="context">The HTTP context for the current request.</param>
|
||||
public async Task InvokeAsync(HttpContext context)
|
||||
{
|
||||
try
|
||||
{
|
||||
await Next(context);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await HandleExceptionAsync(context, ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task HandleExceptionAsync(HttpContext context, Exception exception)
|
||||
{
|
||||
var (statusCode, problemDetails) = MapExceptionToProblemDetails(exception, context);
|
||||
|
||||
context.Response.StatusCode = (int)statusCode;
|
||||
context.Response.ContentType = "application/problem+json";
|
||||
|
||||
await context.Response.WriteAsync(JsonSerializer.Serialize(problemDetails, ProbDetailsJsonOpt));
|
||||
}
|
||||
|
||||
private static (HttpStatusCode StatusCode, ProblemDetails ProblemDetails) MapExceptionToProblemDetails(
|
||||
Exception exception,
|
||||
HttpContext context)
|
||||
{
|
||||
return exception switch
|
||||
{
|
||||
// FluentValidation (400 Bad Request)
|
||||
ValidationException validationEx => (
|
||||
HttpStatusCode.BadRequest,
|
||||
new ProblemDetails
|
||||
{
|
||||
Type = "https://datatracker.ietf.org/doc/html/rfc7231#section-6.5.1",
|
||||
Title = "Validation Error",
|
||||
Status = (int)HttpStatusCode.BadRequest,
|
||||
Detail = string.Join("; ", validationEx.Errors.Select(e => e.ErrorMessage)),
|
||||
Instance = context.Request.Path
|
||||
}
|
||||
),
|
||||
|
||||
// Bad Request Exception (400 Bad Request)
|
||||
BadRequestException badReqEx => (
|
||||
HttpStatusCode.BadRequest,
|
||||
new ProblemDetails
|
||||
{
|
||||
Type = "https://datatracker.ietf.org/doc/html/rfc7231#section-6.5.4",
|
||||
Title = "Bad Request",
|
||||
Status = (int)HttpStatusCode.BadRequest,
|
||||
Detail = badReqEx.Message,
|
||||
Instance = context.Request.Path
|
||||
}
|
||||
),
|
||||
|
||||
// Not Found Exception (404 Not Found)
|
||||
NotFoundException notFoundEx => (
|
||||
HttpStatusCode.NotFound,
|
||||
new ProblemDetails
|
||||
{
|
||||
Type = "https://datatracker.ietf.org/doc/html/rfc7231#section-6.5.4",
|
||||
Title = "Resource Not Found",
|
||||
Status = (int)HttpStatusCode.NotFound,
|
||||
Detail = notFoundEx.Message,
|
||||
Instance = context.Request.Path
|
||||
}
|
||||
),
|
||||
|
||||
// Generic Exception (500 Internal Server Error)
|
||||
_ => (
|
||||
HttpStatusCode.InternalServerError,
|
||||
new ProblemDetails
|
||||
{
|
||||
Type = "https://datatracker.ietf.org/doc/html/rfc7231#section-6.6.1",
|
||||
Title = "Internal Server Error",
|
||||
Status = (int)HttpStatusCode.InternalServerError,
|
||||
Detail = "An unexpected error occurred. Please contact support.",
|
||||
Instance = context.Request.Path
|
||||
}
|
||||
)
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user