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