增加管道异常处理 IExceptionHandler
parent
5d51ac562a
commit
288dacf613
|
@ -79,8 +79,8 @@ var _configuration = builder.Configuration;
|
|||
//手动注册服务
|
||||
builder.Services.ConfigureServices(_configuration);
|
||||
|
||||
//异常处理
|
||||
//builder.Services.AddExceptionHandler<GlobalExceptionHandler>();
|
||||
//minimal api 异常处理
|
||||
builder.Services.AddExceptionHandler<GlobalExceptionHandler>();
|
||||
//builder.Services.AddProblemDetails();
|
||||
|
||||
//健康检查
|
||||
|
@ -148,7 +148,9 @@ builder.Services.AddMasaMinimalAPIs(options =>
|
|||
options.DeletePrefixes = new List<string> { "Delete", "Remove" };
|
||||
|
||||
options.RouteHandlerBuilder= t=> {
|
||||
t.RequireAuthorization().AddEndpointFilter<UnifiedApiResultEndpointFilter>().WithGroupName("Institution");
|
||||
t.RequireAuthorization()
|
||||
.AddEndpointFilter<UnifiedApiResultEndpointFilter>()
|
||||
.WithGroupName("Institution");
|
||||
};
|
||||
options.DisableTrimMethodPrefix = true; //禁用去除方法前缀
|
||||
options.DisableAutoMapRoute = false;//可通过配置true禁用全局自动路由映射或者删除此配置以启用全局自动路由映射
|
||||
|
@ -186,7 +188,8 @@ app.UseStatusCodePages(async context =>
|
|||
|
||||
});
|
||||
|
||||
//app.UseExceptionHandler(o => { });
|
||||
//app.UseExceptionHandler();
|
||||
app.UseExceptionHandler(o => { });
|
||||
|
||||
//这里没生效,原因未知,官方文档也是这种写法,也用了GlobalExceptionHandler 尝试,还是不行,怀疑框架bug
|
||||
//app.UseExceptionHandler(configure =>
|
||||
|
|
|
@ -1,43 +0,0 @@
|
|||
using Microsoft.AspNetCore.Diagnostics;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
|
||||
namespace IRaCIS.Core.Application.BusinessFilter;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 不生效,不知道为啥
|
||||
/// </summary>
|
||||
public class GlobalExceptionHandler : IExceptionHandler
|
||||
{
|
||||
private readonly ILogger<GlobalExceptionHandler> _logger;
|
||||
public GlobalExceptionHandler(ILogger<GlobalExceptionHandler> logger)
|
||||
{
|
||||
this._logger = logger;
|
||||
}
|
||||
public ValueTask<bool> TryHandleAsync(
|
||||
HttpContext httpContext,
|
||||
Exception exception,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
|
||||
|
||||
httpContext.Response.ContentType = "application/json";
|
||||
|
||||
|
||||
var ex = exception;
|
||||
var errorInfo = $"Exception: {ex.Message}[{ex.StackTrace}]" + (ex.InnerException != null ? $" InnerException: {ex.InnerException.Message}[{ex.InnerException.StackTrace}]" : "");
|
||||
|
||||
httpContext.Response.WriteAsJsonAsync(ResponseOutput.NotOk($"{ex?.Message}"));
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
_logger.LogError(errorInfo);
|
||||
|
||||
// return true to signal that this exception is handled
|
||||
return ValueTask.FromResult(false);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
using IRaCIS.Core.Domain.Share;
|
||||
using IRaCIS.Core.Infrastructure;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.Extensions.Localization;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace IRaCIS.Core.Application.Filter;
|
||||
|
||||
public class ProjectExceptionFilter(ILogger<ProjectExceptionFilter> _logger, IStringLocalizer _localizer) : Attribute, IExceptionFilter
|
||||
{
|
||||
|
||||
public void OnException(ExceptionContext context)
|
||||
{
|
||||
//context.ExceptionHandled;//记录当前这个异常是否已经被处理过了
|
||||
|
||||
var exception = context.Exception;
|
||||
|
||||
if (!context.ExceptionHandled)
|
||||
{
|
||||
if (exception.GetType().Name == "DbUpdateConcurrencyException")
|
||||
{
|
||||
//---并发更新,当前不允许该操作
|
||||
context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["ProjectException_ConcurrentUpdateNotAllowed"] + exception.Message));
|
||||
}
|
||||
|
||||
if (exception.GetType() == typeof(BusinessValidationFailedException))
|
||||
{
|
||||
var error = exception as BusinessValidationFailedException;
|
||||
|
||||
var info = string.Empty;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(error!.LocalizedKey) && StaticData.Log_Locoalize_Dic.ContainsKey(error!.LocalizedKey))
|
||||
{
|
||||
info = $"[{error!.LocalizedKey}]:{StaticData.Log_Locoalize_Dic[error!.LocalizedKey]}";
|
||||
}
|
||||
|
||||
|
||||
context.Result = new JsonResult(ResponseOutput.NotOk(exception.Message, "", error!.Code, localizedInfo: info));
|
||||
|
||||
}
|
||||
else if (exception.GetType() == typeof(QueryBusinessObjectNotExistException))
|
||||
{
|
||||
context.Result = new JsonResult(ResponseOutput.NotOk(exception.Message, ApiResponseCodeEnum.DataNotExist));
|
||||
}
|
||||
else
|
||||
{
|
||||
context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["Project_ExceptionContactDeveloper"] + (exception.InnerException is null ? (exception.Message)
|
||||
: (exception.InnerException?.Message )), ApiResponseCodeEnum.ProgramException));
|
||||
|
||||
}
|
||||
|
||||
context.ExceptionHandled = true;//标记当前异常已经被处理过了
|
||||
|
||||
|
||||
var errorInfo = $"Exception: {exception.Message}[{exception.StackTrace}]" + (exception.InnerException != null ? $" InnerException: {exception.InnerException.Message}[{exception.InnerException.StackTrace}]" : "");
|
||||
|
||||
_logger.LogError(errorInfo);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
//继续
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
using DocumentFormat.OpenXml.InkML;
|
||||
using IRaCIS.Core.Infrastructure;
|
||||
using Microsoft.AspNetCore.Diagnostics;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
|
||||
namespace IRaCIS.Core.Application.BusinessFilter;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// minimal api 生效,但是传统控制器,没生效
|
||||
/// 参考处理链接: https://learn.microsoft.com/zh-cn/aspnet/core/fundamentals/error-handling?view=aspnetcore-8.0
|
||||
/// </summary>
|
||||
public class GlobalExceptionHandler(IStringLocalizer _localizer, ILogger<GlobalExceptionHandler> _logger) : IExceptionHandler
|
||||
{
|
||||
|
||||
public ValueTask<bool> TryHandleAsync(
|
||||
HttpContext httpContext,
|
||||
Exception exception,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
|
||||
httpContext.Response.StatusCode =StatusCodes.Status200OK;
|
||||
|
||||
httpContext.Response.ContentType = "application/json";
|
||||
|
||||
if (exception.GetType().Name == "DbUpdateConcurrencyException")
|
||||
{
|
||||
//---并发更新,当前不允许该操作
|
||||
|
||||
httpContext.Response.WriteAsJsonAsync(ResponseOutput.NotOk(_localizer["ProjectException_ConcurrentUpdateNotAllowed"] + exception.Message));
|
||||
}
|
||||
|
||||
if (exception.GetType() == typeof(BusinessValidationFailedException))
|
||||
{
|
||||
var error = exception as BusinessValidationFailedException;
|
||||
|
||||
var info = string.Empty;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(error!.LocalizedKey) && StaticData.Log_Locoalize_Dic.ContainsKey(error!.LocalizedKey))
|
||||
{
|
||||
info = $"[{error!.LocalizedKey}]:{StaticData.Log_Locoalize_Dic[error!.LocalizedKey]}";
|
||||
}
|
||||
|
||||
httpContext.Response.WriteAsJsonAsync(ResponseOutput.NotOk(exception.Message, "", error!.Code, localizedInfo: info));
|
||||
|
||||
|
||||
|
||||
//warning 级别记录
|
||||
//_logger.LogWarning($"[{error!.LocalizedKey}]:{StaticData.Log_Locoalize_Dic[error!.LocalizedKey]}");
|
||||
}
|
||||
else if (exception.GetType() == typeof(QueryBusinessObjectNotExistException))
|
||||
{
|
||||
httpContext.Response.WriteAsJsonAsync(ResponseOutput.NotOk(exception.Message, ApiResponseCodeEnum.DataNotExist));
|
||||
}
|
||||
else
|
||||
{
|
||||
httpContext.Response.WriteAsJsonAsync(ResponseOutput.NotOk(_localizer["Project_ExceptionContactDeveloper"] + (exception.InnerException is null ? (exception.Message )
|
||||
: (exception.InnerException?.Message)), ApiResponseCodeEnum.ProgramException));
|
||||
|
||||
}
|
||||
|
||||
var errorInfo = $"Exception: {exception.Message}[{exception.StackTrace}]" + (exception.InnerException != null ? $" InnerException: {exception.InnerException.Message}[{exception.InnerException.StackTrace}]" : "");
|
||||
|
||||
_logger.LogError(errorInfo);
|
||||
|
||||
// Return false to continue with the default behavior
|
||||
// - or - return true to signal that this exception is handled
|
||||
return ValueTask.FromResult(false);
|
||||
}
|
||||
}
|
|
@ -1,75 +0,0 @@
|
|||
using IRaCIS.Core.Domain.Share;
|
||||
using IRaCIS.Core.Infrastructure;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.Extensions.Localization;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace IRaCIS.Core.Application.Filter;
|
||||
|
||||
public class ProjectExceptionFilter : Attribute, IExceptionFilter
|
||||
{
|
||||
private readonly ILogger<ProjectExceptionFilter> _logger;
|
||||
|
||||
public IStringLocalizer _localizer;
|
||||
|
||||
public ProjectExceptionFilter(IStringLocalizer localizer, ILogger<ProjectExceptionFilter> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
_localizer = localizer;
|
||||
}
|
||||
public void OnException(ExceptionContext context)
|
||||
{
|
||||
//context.ExceptionHandled;//记录当前这个异常是否已经被处理过了
|
||||
|
||||
if (!context.ExceptionHandled)
|
||||
{
|
||||
if (context.Exception.GetType().Name == "DbUpdateConcurrencyException")
|
||||
{
|
||||
//---并发更新,当前不允许该操作
|
||||
context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["ProjectException_ConcurrentUpdateNotAllowed"] + context.Exception.Message));
|
||||
}
|
||||
|
||||
if (context.Exception.GetType() == typeof(BusinessValidationFailedException))
|
||||
{
|
||||
var error = context.Exception as BusinessValidationFailedException;
|
||||
|
||||
var info = string.Empty;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(error!.LocalizedKey) && StaticData.Log_Locoalize_Dic.ContainsKey(error!.LocalizedKey))
|
||||
{
|
||||
info = $"[{error!.LocalizedKey}]:{StaticData.Log_Locoalize_Dic[error!.LocalizedKey]}";
|
||||
}
|
||||
|
||||
|
||||
context.Result = new JsonResult(ResponseOutput.NotOk(context.Exception.Message, "", error!.Code, localizedInfo: info));
|
||||
|
||||
|
||||
//warning 级别记录
|
||||
//_logger.LogWarning($"[{error!.LocalizedKey}]:{StaticData.Log_Locoalize_Dic[error!.LocalizedKey]}");
|
||||
}
|
||||
else if (context.Exception.GetType() == typeof(QueryBusinessObjectNotExistException))
|
||||
{
|
||||
context.Result = new JsonResult(ResponseOutput.NotOk(context.Exception.Message, ApiResponseCodeEnum.DataNotExist));
|
||||
}
|
||||
else
|
||||
{
|
||||
context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["Project_ExceptionContactDeveloper"] + (context.Exception.InnerException is null ? (context.Exception.Message /*+ context.Exception.StackTrace*/)
|
||||
: (context.Exception.InnerException?.Message /*+ context.Exception.InnerException?.StackTrace*/)), ApiResponseCodeEnum.ProgramException));
|
||||
|
||||
_logger.LogError(context.Exception.InnerException is null ? (context.Exception.Message + context.Exception.StackTrace) : (context.Exception.InnerException?.Message + context.Exception.InnerException?.StackTrace));
|
||||
|
||||
}
|
||||
|
||||
context.ExceptionHandled = true;//标记当前异常已经被处理过了
|
||||
|
||||
|
||||
//throw new Exception("test-result-exceptioin");
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
//继续
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12717,7 +12717,14 @@
|
|||
</member>
|
||||
<member name="T:IRaCIS.Core.Application.BusinessFilter.GlobalExceptionHandler">
|
||||
<summary>
|
||||
不生效,不知道为啥
|
||||
minimal api 生效,但是传统控制器,没生效
|
||||
参考处理链接: https://learn.microsoft.com/zh-cn/aspnet/core/fundamentals/error-handling?view=aspnetcore-8.0
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.Application.BusinessFilter.GlobalExceptionHandler.#ctor(Microsoft.Extensions.Localization.IStringLocalizer,Microsoft.Extensions.Logging.ILogger{IRaCIS.Core.Application.BusinessFilter.GlobalExceptionHandler})">
|
||||
<summary>
|
||||
minimal api 生效,但是传统控制器,没生效
|
||||
参考处理链接: https://learn.microsoft.com/zh-cn/aspnet/core/fundamentals/error-handling?view=aspnetcore-8.0
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:IRaCIS.Core.Application.Filter.TrialResourceFilter">
|
||||
|
|
|
@ -58,6 +58,8 @@ namespace IRaCIS.Core.Application.Service
|
|||
|
||||
public IResponseOutput GetTest()
|
||||
{
|
||||
throw new BusinessValidationFailedException("手动抛出的异常");
|
||||
|
||||
return ResponseOutput.Ok(_userInfo.IP);
|
||||
}
|
||||
}
|
||||
|
@ -167,6 +169,8 @@ namespace IRaCIS.Core.Application.Service
|
|||
|
||||
public async Task<IResponseOutput> TestJson()
|
||||
{
|
||||
throw new BusinessValidationFailedException("传统控制器异常");
|
||||
|
||||
var model1 = new TestModel() { TestId = NewId.NextSequentialGuid(), TestName = null };
|
||||
var model2 = new TestModel2() { TestId = NewId.NextSequentialGuid(), TestName = "test2" };
|
||||
|
||||
|
|
Loading…
Reference in New Issue