Home > Software engineering >  How do I handle Exception throw by Intercepter in C#
How do I handle Exception throw by Intercepter in C#

Time:11-30

I want to Catch the exceptions thrown by Interceptor, how can I do it?

using autofac6.0.0,.NET 6

Controller>CommandAspect>Commands

The Interceptor can catch Exceptions from Command, but the Controller does not catch Exceptions from the Interceptor.

register

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;
        }
    }
}

WebController

try
{
    type commandType = typeof(CommandClass);
    object commandObject = _serviceProvider.GetService(commandType);
    commandType.GetMethod("SomeCommand").Invoke(commandObject);
}
catch(Exception ex)
{
   //not handled
}

Command

 public class CommandClass : ICommand
 {
     public virtual void SomeCommand()
     {
       throw new Exception();
     }
  }

Exception StackTrace

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()

Resoleved

 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;
        }
    }
}

CodePudding user response:

You're not doing async interception right. You have to return void from Intercept and set the ReturnValue to the Task result. See the docs here..

Your stack trace shows the exception coming from a different thread, hence it's not being caught. If you set up the interceptor right, I bet it'll work as expected.

CodePudding user response:

You can implement an ErrorHandling middleware to handle this. Since middleware is acting outside the controller, the controller doesn't get to see the error.

Have a look at this link: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/error-handling?view=aspnetcore-6.0

  • Related