如何在 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..

您的堆栈跟踪显示异常来自不同的线程,因此未被捕获。如果您正确设置拦截器,我敢打赌它会按预期工作。