增加管道异常处理 IExceptionHandler
parent
5d51ac562a
commit
288dacf613
|
@ -79,8 +79,8 @@ var _configuration = builder.Configuration;
|
||||||
//手动注册服务
|
//手动注册服务
|
||||||
builder.Services.ConfigureServices(_configuration);
|
builder.Services.ConfigureServices(_configuration);
|
||||||
|
|
||||||
//异常处理
|
//minimal api 异常处理
|
||||||
//builder.Services.AddExceptionHandler<GlobalExceptionHandler>();
|
builder.Services.AddExceptionHandler<GlobalExceptionHandler>();
|
||||||
//builder.Services.AddProblemDetails();
|
//builder.Services.AddProblemDetails();
|
||||||
|
|
||||||
//健康检查
|
//健康检查
|
||||||
|
@ -148,7 +148,9 @@ builder.Services.AddMasaMinimalAPIs(options =>
|
||||||
options.DeletePrefixes = new List<string> { "Delete", "Remove" };
|
options.DeletePrefixes = new List<string> { "Delete", "Remove" };
|
||||||
|
|
||||||
options.RouteHandlerBuilder= t=> {
|
options.RouteHandlerBuilder= t=> {
|
||||||
t.RequireAuthorization().AddEndpointFilter<UnifiedApiResultEndpointFilter>().WithGroupName("Institution");
|
t.RequireAuthorization()
|
||||||
|
.AddEndpointFilter<UnifiedApiResultEndpointFilter>()
|
||||||
|
.WithGroupName("Institution");
|
||||||
};
|
};
|
||||||
options.DisableTrimMethodPrefix = true; //禁用去除方法前缀
|
options.DisableTrimMethodPrefix = true; //禁用去除方法前缀
|
||||||
options.DisableAutoMapRoute = false;//可通过配置true禁用全局自动路由映射或者删除此配置以启用全局自动路由映射
|
options.DisableAutoMapRoute = false;//可通过配置true禁用全局自动路由映射或者删除此配置以启用全局自动路由映射
|
||||||
|
@ -186,7 +188,8 @@ app.UseStatusCodePages(async context =>
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
//app.UseExceptionHandler(o => { });
|
//app.UseExceptionHandler();
|
||||||
|
app.UseExceptionHandler(o => { });
|
||||||
|
|
||||||
//这里没生效,原因未知,官方文档也是这种写法,也用了GlobalExceptionHandler 尝试,还是不行,怀疑框架bug
|
//这里没生效,原因未知,官方文档也是这种写法,也用了GlobalExceptionHandler 尝试,还是不行,怀疑框架bug
|
||||||
//app.UseExceptionHandler(configure =>
|
//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>
|
||||||
<member name="T:IRaCIS.Core.Application.BusinessFilter.GlobalExceptionHandler">
|
<member name="T:IRaCIS.Core.Application.BusinessFilter.GlobalExceptionHandler">
|
||||||
<summary>
|
<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>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
<member name="T:IRaCIS.Core.Application.Filter.TrialResourceFilter">
|
<member name="T:IRaCIS.Core.Application.Filter.TrialResourceFilter">
|
||||||
|
|
|
@ -58,6 +58,8 @@ namespace IRaCIS.Core.Application.Service
|
||||||
|
|
||||||
public IResponseOutput GetTest()
|
public IResponseOutput GetTest()
|
||||||
{
|
{
|
||||||
|
throw new BusinessValidationFailedException("手动抛出的异常");
|
||||||
|
|
||||||
return ResponseOutput.Ok(_userInfo.IP);
|
return ResponseOutput.Ok(_userInfo.IP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -167,6 +169,8 @@ namespace IRaCIS.Core.Application.Service
|
||||||
|
|
||||||
public async Task<IResponseOutput> TestJson()
|
public async Task<IResponseOutput> TestJson()
|
||||||
{
|
{
|
||||||
|
throw new BusinessValidationFailedException("传统控制器异常");
|
||||||
|
|
||||||
var model1 = new TestModel() { TestId = NewId.NextSequentialGuid(), TestName = null };
|
var model1 = new TestModel() { TestId = NewId.NextSequentialGuid(), TestName = null };
|
||||||
var model2 = new TestModel2() { TestId = NewId.NextSequentialGuid(), TestName = "test2" };
|
var model2 = new TestModel2() { TestId = NewId.NextSequentialGuid(), TestName = "test2" };
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue