Is it possible to write a Castle DynamicProxy Interceptor (for use with an IoC framework) that will allow you to wrap an exception being thrown by the class being intercepted?
I have a class which is throwing a SqlException
, and I want to have that wrapped in a custom class called MyCustomSqlException
. When the intercepted class is synchronous then this is trivial because I can use a simple try catch block to deal with wrapping the SqlException
and throwing the MyCustomSqlException
.
The problem comes in when the intercepted class has async methods which return a task, in a faulted state. When testing the interceptor, the only way to get the interceptor exposing the MyCustomSqlException
was to wait on the intercepted task within the interceptor.
If I did not wait for the intercepted task, then after the interceptor has been executed and the calling code has awaited the methods, I still have the SqlException
being thrown rather than the MyCustomSqlException
.
I have the following implementation which works but I am concerned that having a .Wait()
statement in there will mean that the interceptor will become blocking whilst waiting for the intercepted class to complete it's work.
public class CustomSqlExceptionInterceptor : IInterceptor
{
private readonly string _databaseName;
public CustomSqlExceptionInterceptor(string databaseName)
{
_databaseName = databaseName;
}
public void Intercept(IInvocation invocation)
{
try
{
invocation.Proceed();
if (invocation.ReturnValue is Task task)
{
var wrappingTask = task.ContinueWith(previousTask =>
{
previousTask.Exception.Handle(inner =>
throw new MyCustomSqlException($"Error from {_databaseName} database", inner)
);
}, TaskContinuationOptions.OnlyOnFaulted);
wrappingTask.Wait(); //TODO: Will this cause I/O issues?
}
}
catch (SqlException inner)
{
throw new MyCustomSqlException($"Error from {_databaseName} database", inner);
}
}
}
I am trying to write this in C# on .Net Core 2.1