171 lines
5.3 KiB
C#
171 lines
5.3 KiB
C#
using System.ComponentModel.DataAnnotations;
|
|
using e_suite.API.Common;
|
|
using e_suite.API.Common.exceptions;
|
|
using e_suite.Database.Core.Extensions.Exceptions;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Newtonsoft.Json;
|
|
|
|
namespace eSuite.API.Middleware;
|
|
|
|
/// <summary>
|
|
/// Exception capture middleware
|
|
/// </summary>
|
|
public class ExceptionCapture
|
|
{
|
|
private readonly RequestDelegate _next;
|
|
private readonly IExceptionLogManager _exceptionLogManager;
|
|
|
|
/// <summary>
|
|
/// Default constructor
|
|
/// </summary>
|
|
/// <param name="next"></param>
|
|
/// <param name="exceptionLogManager"></param>
|
|
public ExceptionCapture(RequestDelegate next, IExceptionLogManager exceptionLogManager)
|
|
{
|
|
_next = next;
|
|
_exceptionLogManager = exceptionLogManager;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Called to wrap the controller method with general graceful error handling
|
|
/// </summary>
|
|
/// <param name="context"></param>
|
|
/// <returns></returns>
|
|
public async Task InvokeAsync(HttpContext context)
|
|
{
|
|
try
|
|
{
|
|
await _next.Invoke(context);
|
|
}
|
|
catch (GuidMismatchException ex)
|
|
{
|
|
await BadRequestResponse(context, ex);
|
|
}
|
|
catch (NotFoundException ex)
|
|
{
|
|
await NotFoundResponse(context, ex);
|
|
}
|
|
catch (ExistsException ex)
|
|
{
|
|
await BadRequestResponse(context, ex);
|
|
}
|
|
catch (InvalidOperationException ex)
|
|
{
|
|
await BadRequestResponse(context, ex);
|
|
}
|
|
catch( ValidationException ex)
|
|
{
|
|
await BadRequestResponse(context, ex);
|
|
}
|
|
catch (ArgumentException ex)
|
|
{
|
|
await BadRequestResponse(context, ex);
|
|
}
|
|
catch (InvalidReferenceObjectId ex)
|
|
{
|
|
await BadRequestResponse(context, ex);
|
|
}
|
|
catch (TokenInvalidException ex)
|
|
{
|
|
await BadRequestResponse(context, ex);
|
|
}
|
|
catch (InvalidEmailException ex)
|
|
{
|
|
await BadRequestResponse(context, ex);
|
|
}
|
|
catch (MinimumRangeException ex)
|
|
{
|
|
await BadRequestResponse(context, ex);
|
|
}
|
|
catch (MaximumRangeException ex)
|
|
{
|
|
await BadRequestResponse(context, ex);
|
|
}
|
|
catch (OperationCanceledException ex)
|
|
{
|
|
await BadRequestResponse(context, ex, "Request cancelled");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
var supportingData = new
|
|
{
|
|
User = context.User.Identity != null ? context.User.Identity.Name : string.Empty,
|
|
context.Request.Query,
|
|
context.Request.Method,
|
|
context.Request.Path,
|
|
context.Request.Headers,
|
|
context.Request.Cookies,
|
|
context.Request.QueryString,
|
|
context.Items
|
|
}.ToJson();
|
|
|
|
var exceptionId = await _exceptionLogManager.LogException(ex, "e-suite API", supportingData, CancellationToken.None);
|
|
await InternalServerErrorResponse(context, ex, exceptionId);
|
|
}
|
|
}
|
|
|
|
private static async Task BadRequestResponse(HttpContext context, Exception ex, string title = "Bad request")
|
|
{
|
|
var problemDetails = new ProblemDetails
|
|
{
|
|
Title = title,
|
|
Detail = ex.Message
|
|
};
|
|
|
|
context.Response.StatusCode = StatusCodes.Status400BadRequest;
|
|
context.Response.ContentType = "application/json";
|
|
|
|
await context.Response.WriteAsync(problemDetails.ToJson());
|
|
}
|
|
|
|
private static async Task NotFoundResponse(HttpContext context, Exception ex, string title = "Not found")
|
|
{
|
|
var problemDetails = new ProblemDetails
|
|
{
|
|
Title = title,
|
|
Detail = ex.Message
|
|
};
|
|
|
|
context.Response.StatusCode = StatusCodes.Status404NotFound;
|
|
context.Response.ContentType = "application/json";
|
|
|
|
await context.Response.WriteAsync(problemDetails.ToJson());
|
|
}
|
|
|
|
private static async Task InternalServerErrorResponse(HttpContext context, Exception ex, long exceptionId, string title = "Internal Server Error")
|
|
{
|
|
var problemDetails = new ProblemDetails
|
|
{
|
|
Title = title,
|
|
Detail = ex.Message,
|
|
Instance = exceptionId.ToString()
|
|
};
|
|
|
|
context.Response.StatusCode = StatusCodes.Status500InternalServerError;
|
|
context.Response.ContentType = "application/json";
|
|
|
|
await context.Response.WriteAsync(problemDetails.ToJson());
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public static class ObjectExtensions
|
|
{
|
|
/// <summary>
|
|
/// Serialize the current object to Json
|
|
/// </summary>
|
|
/// <param name="value"></param>
|
|
/// <returns></returns>
|
|
public static string ToJson(this object value)
|
|
{
|
|
var options = new JsonSerializerSettings
|
|
{
|
|
Formatting = Formatting.Indented,
|
|
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
|
|
NullValueHandling = NullValueHandling.Include
|
|
};
|
|
return JsonConvert.SerializeObject(value, options);
|
|
}
|
|
} |