141 lines
5.1 KiB
C#
141 lines
5.1 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Net;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using iPackage.Models.Api;
|
|
using Microsoft.AspNetCore.Builder;
|
|
using Microsoft.AspNetCore.Hosting;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.Extensions.Logging;
|
|
using Microsoft.IdentityModel.Tokens;
|
|
using Newtonsoft.Json;
|
|
|
|
namespace iPackage.Core.Web.WebFramework.Middlewares
|
|
{
|
|
public static class ExceptionHandlerMiddlewareExtensions
|
|
{
|
|
public static IApplicationBuilder UseExceptionHandlerMiddleware(this IApplicationBuilder applicationBuilder)
|
|
{
|
|
return applicationBuilder.UseMiddleware<ExceptionHandlerMiddleware>();
|
|
}
|
|
}
|
|
public class ExceptionHandlerMiddleware
|
|
{
|
|
private readonly RequestDelegate _next;
|
|
private readonly IHostingEnvironment _env;
|
|
private readonly ILogger<ExceptionHandlerMiddleware> _logger;
|
|
|
|
public ExceptionHandlerMiddleware(RequestDelegate next,
|
|
IHostingEnvironment env,
|
|
ILogger<ExceptionHandlerMiddleware> logger)
|
|
{
|
|
_next = next;
|
|
_env = env;
|
|
_logger = logger;
|
|
}
|
|
|
|
public async Task Invoke(HttpContext context)
|
|
{
|
|
string message = null;
|
|
HttpStatusCode httpStatusCode = HttpStatusCode.InternalServerError;
|
|
ApiResultStatusCode apiStatusCode = ApiResultStatusCode.ServerError;
|
|
|
|
try
|
|
{
|
|
await _next(context);
|
|
}
|
|
catch (AppException exception)
|
|
{
|
|
_logger.LogError(exception, exception.Message);
|
|
httpStatusCode = exception.HttpStatusCode;
|
|
apiStatusCode = exception.ApiStatusCode;
|
|
|
|
if (_env.IsDevelopment())
|
|
{
|
|
var dic = new Dictionary<string, string>
|
|
{
|
|
["Exception"] = exception.Message,
|
|
["StackTrace"] = exception.StackTrace,
|
|
};
|
|
if (exception.InnerException != null)
|
|
{
|
|
dic.Add("InnerException.Exception", exception.InnerException.Message);
|
|
dic.Add("InnerException.StackTrace", exception.InnerException.StackTrace);
|
|
}
|
|
if (exception.AdditionalData != null)
|
|
dic.Add("AdditionalData", JsonConvert.SerializeObject(exception.AdditionalData));
|
|
|
|
message = JsonConvert.SerializeObject(dic);
|
|
}
|
|
else
|
|
{
|
|
message = exception.Message;
|
|
}
|
|
await WriteToResponseAsync();
|
|
}
|
|
catch (SecurityTokenExpiredException exception)
|
|
{
|
|
_logger.LogError(exception, exception.Message);
|
|
SetUnAuthorizeResponse(exception);
|
|
await WriteToResponseAsync();
|
|
}
|
|
catch (UnauthorizedAccessException exception)
|
|
{
|
|
_logger.LogError(exception, exception.Message);
|
|
SetUnAuthorizeResponse(exception);
|
|
await WriteToResponseAsync();
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
_logger.LogError(exception, exception.Message);
|
|
|
|
if (_env.IsDevelopment())
|
|
{
|
|
var dic = new Dictionary<string, string>
|
|
{
|
|
["Exception"] = exception.Message,
|
|
["InnerException"] = exception.InnerException?.Message,
|
|
["StackTrace"] = exception.StackTrace,
|
|
};
|
|
message = JsonConvert.SerializeObject(dic);
|
|
}
|
|
await WriteToResponseAsync();
|
|
}
|
|
|
|
async Task WriteToResponseAsync()
|
|
{
|
|
if (context.Response.HasStarted)
|
|
throw new InvalidOperationException("The response has already started, the http status code middleware will not be executed.");
|
|
|
|
var result = new ApiResult(false, apiStatusCode, message);
|
|
var json = JsonConvert.SerializeObject(result);
|
|
|
|
context.Response.StatusCode = (int)httpStatusCode;
|
|
context.Response.ContentType = "application/json";
|
|
await context.Response.WriteAsync(json);
|
|
}
|
|
|
|
void SetUnAuthorizeResponse(Exception exception)
|
|
{
|
|
httpStatusCode = HttpStatusCode.Unauthorized;
|
|
apiStatusCode = ApiResultStatusCode.UnAuthorized;
|
|
|
|
if (_env.IsDevelopment())
|
|
{
|
|
var dic = new Dictionary<string, string>
|
|
{
|
|
["Exception"] = exception.Message,
|
|
["StackTrace"] = exception.StackTrace
|
|
};
|
|
if (exception is SecurityTokenExpiredException tokenException)
|
|
dic.Add("Expires", tokenException.Expires.ToString());
|
|
|
|
message = JsonConvert.SerializeObject(dic);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|