如何在 C# 中处理拦截器抛出的异常
How do I handle Exception throw by Intercepter in C#
我想捕获Interceptor抛出的异常,怎么办?
使用 autofac6.0.0,.NET 6
控制器>CommandAspect>命令
拦截器可以捕获来自命令的异常,但控制器不会捕获来自拦截器的异常。
注册
builder.RegisterModule<AutofacScanningModule>();
builder.RegisterType<CommandAspect>();
AutofacScanningModule
public class AutofacScanningModule : Module
{
protected override void Load(ContainerBuilder builder)
{
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
builder
.RegisterAssemblyTypes(assemblies)
.Where(t => t.GetInterfaces().Any(i => i.IsAssignableFrom(typeof(ICommand))))
.EnableClassInterceptors()
.InterceptedBy(typeof(CommandAspect));
base.Load(builder);
}
}
CommandAspect
public class CommandAspect : IInterceptor
{
public CommandAspect()
{
}
public async void Intercept(IInvocation invocation)
{
try
{
invocation.Proceed();
}
catch (Exception ex)
{
//Log Output
throw;
}
}
}
网络控制器
try
{
type commandType = typeof(CommandClass);
object commandObject = _serviceProvider.GetService(commandType);
commandType.GetMethod("SomeCommand").Invoke(commandObject);
}
catch(Exception ex)
{
//not handled
}
命令
public class CommandClass : ICommand
{
public virtual void SomeCommand()
{
throw new Exception();
}
}
异常堆栈跟踪
Unhandled exception. System.Exception: Exception of type 'System.Exception' was thrown.
at Sample.SomeCommand.Find(Record record) SomeCommand.cs:line 42
at Castle.Proxies.SomeCommandProxy.Find_callback(Record record)
at Castle.Proxies.Invocations.SomeCommand_Find.InvokeMethodOnTarget()
at Castle.DynamicProxy.AbstractInvocation.Proceed()
at Sample.CommandAspect.Intercept(IInvocation invocation) CommandAspect.cs:line 29
at System.Threading.Tasks.Task.<>c.<ThrowAsync>b__127_1(Object state)
at System.Threading.QueueUserWorkItemCallback.<>c.<.cctor>b__6_0(QueueUserWorkItemCallback quwi)
at System.Threading.ExecutionContext.RunForThreadPoolUnsafe[TState](ExecutionContext executionContext, Action`1 callb
ack, TState& state)
at System.Threading.QueueUserWorkItemCallback.Execute()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading.PortableThreadPool.WorkerThread.WorkerThreadStart()
at System.Threading.Thread.StartCallback()
已解决
public class CommandAspect : IInterceptor
{
public CommandAspect()
{
}
public void Intercept(IInvocation invocation)
{
ProcessInterceptAsync(invocation).Wait();
}
private async Task ProcessInterceptAsync(IInvocation invocation)
{
try
{
var proceed = invocation.CaptureProceedInfo();
proceed.Invoke();
}
catch (Exception ex)
{
//Log Output
throw;
}
}
}
您可以实现一个 ErrorHandling
中间件来处理这个问题。由于中间件在控制器外部运行,因此控制器看不到错误。
看看这个 link:
https://docs.microsoft.com/en-us/aspnet/core/fundamentals/error-handling?view=aspnetcore-6.0
你没有做正确的异步拦截。您必须从 Intercept
return void
并将 ReturnValue
设置为 Task
结果。 See the docs here..
您的堆栈跟踪显示异常来自不同的线程,因此未被捕获。如果您正确设置拦截器,我敢打赌它会按预期工作。
我想捕获Interceptor抛出的异常,怎么办?
使用 autofac6.0.0,.NET 6
控制器>CommandAspect>命令
拦截器可以捕获来自命令的异常,但控制器不会捕获来自拦截器的异常。
注册
builder.RegisterModule<AutofacScanningModule>();
builder.RegisterType<CommandAspect>();
AutofacScanningModule
public class AutofacScanningModule : Module
{
protected override void Load(ContainerBuilder builder)
{
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
builder
.RegisterAssemblyTypes(assemblies)
.Where(t => t.GetInterfaces().Any(i => i.IsAssignableFrom(typeof(ICommand))))
.EnableClassInterceptors()
.InterceptedBy(typeof(CommandAspect));
base.Load(builder);
}
}
CommandAspect
public class CommandAspect : IInterceptor
{
public CommandAspect()
{
}
public async void Intercept(IInvocation invocation)
{
try
{
invocation.Proceed();
}
catch (Exception ex)
{
//Log Output
throw;
}
}
}
网络控制器
try
{
type commandType = typeof(CommandClass);
object commandObject = _serviceProvider.GetService(commandType);
commandType.GetMethod("SomeCommand").Invoke(commandObject);
}
catch(Exception ex)
{
//not handled
}
命令
public class CommandClass : ICommand
{
public virtual void SomeCommand()
{
throw new Exception();
}
}
异常堆栈跟踪
Unhandled exception. System.Exception: Exception of type 'System.Exception' was thrown.
at Sample.SomeCommand.Find(Record record) SomeCommand.cs:line 42
at Castle.Proxies.SomeCommandProxy.Find_callback(Record record)
at Castle.Proxies.Invocations.SomeCommand_Find.InvokeMethodOnTarget()
at Castle.DynamicProxy.AbstractInvocation.Proceed()
at Sample.CommandAspect.Intercept(IInvocation invocation) CommandAspect.cs:line 29
at System.Threading.Tasks.Task.<>c.<ThrowAsync>b__127_1(Object state)
at System.Threading.QueueUserWorkItemCallback.<>c.<.cctor>b__6_0(QueueUserWorkItemCallback quwi)
at System.Threading.ExecutionContext.RunForThreadPoolUnsafe[TState](ExecutionContext executionContext, Action`1 callb
ack, TState& state)
at System.Threading.QueueUserWorkItemCallback.Execute()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading.PortableThreadPool.WorkerThread.WorkerThreadStart()
at System.Threading.Thread.StartCallback()
已解决
public class CommandAspect : IInterceptor
{
public CommandAspect()
{
}
public void Intercept(IInvocation invocation)
{
ProcessInterceptAsync(invocation).Wait();
}
private async Task ProcessInterceptAsync(IInvocation invocation)
{
try
{
var proceed = invocation.CaptureProceedInfo();
proceed.Invoke();
}
catch (Exception ex)
{
//Log Output
throw;
}
}
}
您可以实现一个 ErrorHandling
中间件来处理这个问题。由于中间件在控制器外部运行,因此控制器看不到错误。
看看这个 link: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/error-handling?view=aspnetcore-6.0
你没有做正确的异步拦截。您必须从 Intercept
return void
并将 ReturnValue
设置为 Task
结果。 See the docs here..
您的堆栈跟踪显示异常来自不同的线程,因此未被捕获。如果您正确设置拦截器,我敢打赌它会按预期工作。