0

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;
        }
    }
}
love fox
  • 3
  • 2

2 Answers2

0

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://learn.microsoft.com/en-us/aspnet/core/fundamentals/error-handling?view=aspnetcore-6.0

Code Name Jack
  • 2,856
  • 24
  • 40
  • I tried writing app.UseDeveloperExceptionPage(); but the app terminated after the Exception even in Debug. – love fox Nov 29 '21 at 05:18
  • I was talking about using the middleware like, this answer, https://stackoverflow.com/questions/38630076/asp-net-core-web-api-exception-handling – Code Name Jack Nov 29 '21 at 08:04
  • to debug can you add a global try catch in your Main method, to see what really is failing. – Code Name Jack Nov 29 '21 at 08:04
  • It is Web Application. so I tried to write Try Catch in Program.cs , but I couldn't catch it... Thank you for helpfule – love fox Nov 29 '21 at 11:49
  • Even a web application has a main method. Anyways you should be able to catch the exception there. Otherwise if using Visual Studio, you can enable `break on all exception`. This way you would be able to catch them early. – Code Name Jack Nov 29 '21 at 13:10
0

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.

Travis Illig
  • 23,195
  • 2
  • 62
  • 85