3

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

Travis Illig
  • 23,195
  • 2
  • 62
  • 85
Pervez Choudhury
  • 2,892
  • 3
  • 27
  • 28

0 Answers0