Cannot seem to get the last piece of the puzzle into place. Appreciate any assistance :)
I have an interceptor that is logging the parameters and the return of the methods that I want to intercept. The interceptor method is as per below code (I am using .Net 6):
public override async void Intercept(IInvocation invocation)
{
//Initial Logging
object? result = null;
Exception? taskException = null;
try
{
invocation.Proceed();
//This method retrieves the result from the invocation.Result according to whether the method being intercepted is synchronous, asynchronous returning void (Task) or asynchronous returning T (Task<T>).
result = await Result(invocation);
}
catch
{
//Only throw the exception if the method is not asynchronous
Type returnType = invocation.Method.ReturnType;
if (!(returnType == typeof(Task) || (returnType.IsGenericType && returnType.GetGenericTypeDefinition() == typeof(Task<>))))
{
throw;
}
}
finally
{
//More logging
}
}
I have 6 scenarios (methods with different return types) as per below:
# | Description | Result |
---|---|---|
1 | Asynchronous method with return Task and return a successful response | I manage to get the result as expected |
2 | Asynchronous method with return Task and return an exception | I manage to capture the exception as expected |
3 | Asynchronous method with return Task and no exception returned | Working as expected |
4 | Asynchronous method with return Task and return an exception | I manage to capture the exception as expected |
5 | Synchronous method with return bool and return a successful response | I manage to get the result as expected |
6 | Synchronous method with return bool and return an exception | Application is crashing due to error 'Interceptors failed to set a return value, or swallowed the exception thrown by the target' |
5 scenarios seem to work without any issue, but scenario 6 is returning an exception.
When I tried to remove the async keyword, scenario 6 worked a but as expected but scenarios 1 and 3, in the finally block statement, I was not able to get the actual result that the intercepted method was returning since I am never awaiting the result of the method.
Possible solutions that I can think of:
If more information is required, let me know and I'll try to provide as much information as possible.
Thanks in advance
You could move the content of Interceptor
into an inner logic, like
protected void InterceptCore(IInvocation invocation)
{
//Initial Logging
object? result = null;
Exception? taskException = null;
try
{
invocation.Proceed();
//This method retrieves the result from the invocation.Result according to whether the method being intercepted is synchronous, asynchronous returning void (Task) or asynchronous returning T (Task<T>).
result = await Result(invocation);
}
catch
{
//Only throw the exception if the method is not asynchronous
Type returnType = invocation.Method.ReturnType;
if (!(returnType == typeof(Task) || (returnType.IsGenericType && returnType.GetGenericTypeDefinition() == typeof(Task<>))))
{
throw;
}
}
finally
{
//More logging
}
}
And implement another asynchronous method for doing it asynchronously:
public async void InterceptCoreAsync(IInvocation invocation)
{
InterceptCore(invocation);
}
Now, let's overload and override Intercept
:
public override void Intercept(IInvocation invocation)
{
Intercept(invocation, true);
}
public void Intercept(IInvocation invocation, bool IsAsync)
{
IsAsync ? InterceptCoreAsync(invocation) : InterceptCore(invocation);
}