Catching exceptions in CallHandlers

Apr 1, 2009 at 5:12 PM
Edited Apr 1, 2009 at 5:14 PM

I'm looking for an example of how Imight use Unity and interception to do some logging of entry, exit and exception handling. I’ve managed to put together the entry, exit part but not the exception trapping:

 

        public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)

        {

            IMethodReturn val = null;

            Console.WriteLine("[Entering method: {0}]", input.MethodBase.Name);            
            try

            {

                val = getNext().Invoke(input, getNext);

            }

            catch (Exception exc)

            {

                Console.WriteLine("[Exception: {0}", exc);

                throw;

            }

            Console.WriteLine("[Exiting method: {0}]", input.MethodBase.Name);

            return val;

        }

Because of the chained nature of the invocation – it appears that the catch block never gets executed. How might you implement this scenario using unity’s interception?

Apr 2, 2009 at 12:25 AM
If an exception is thrown by the target method, it's captured into the IMethodReturn object, not thrown. The design is that if the target throws, it goes into the MethodReturn. If a handler throws, it goes as a normal exception. The theory being that doing something if the target throws an exception in a handler isn't an exceptional thing to do.

Anyway, in your code, instead of a try catch, do something like this:

val = getNext()(input, getNext);
if(val.Exception != null) {
    Console.WriteLine("Exception: {0}", val.Exception);
}

return val;

Jun 8, 2009 at 6:02 PM

Hi there

I was trying the get the same beahviour explained in this post but i am geting  strange result.

My handler is like this:

 

 

 

 

 

 

 

 

 

public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
        {
            IMethodReturn val;
            val = getNext()(input, getNext);

            if (val.Exception != null)
            {
                Console.WriteLine("Exception has been thrown");
                Console.WriteLine(val.Exception.Message.ToString());
                Console.WriteLine("[Exiting method: {0}]", input.MethodBase.Name);
                return input.CreateExceptionMethodReturn(val.Exception);

            }
            else
            {
                Console.WriteLine("[Exiting method: {0}]", input.MethodBase.Name);
                return val;
            }

           

        }

 

<font size="2" color="#0000ff"><font size="2" color="#0000ff">

If i dont wrap the method call that raises the exception with a try catch block the exception handler is called over and over again. Is there some way to stop this?

</font></font><font size="2" color="#0000ff">

 

</font>

 

Jun 9, 2009 at 3:01 AM

I've never seen that behavior. Could you please post a small, complete example that demonstrates the problem?

Thanks,

-Chris

Jun 9, 2009 at 3:34 AM

Also, one minor thing. If you're not replacing the exception, you don't have to do "return input.CreateExceptionMessageReturn(val.Exception);", you can just return val. It's already set up with the thrown exception inside it.

 

Jun 29, 2009 at 3:23 PM
Hi
 
First of all let me apologize for the delay, i´ve been very busy :)
 
I have a few classes to show you this, i will post them. If you like i could send them to you but here it goes
 
1.  Console class
1. Console class
 #region Unity Interception
            UnityContainer _container = new UnityContainer();
            _container.RegisterType<IBusinessLayerClass1, BusinessLayerClass1>();
            _container.AddNewExtension<Interception>();
            _container.Configure<Interception>()
                .SetDefaultInterceptorFor<IBusinessLayerClass1>(new InterfaceInterceptor())
                .AddPolicy("ExceptionPolicy")
                    .AddMatchingRule(new AssemblyMatchingRule("UnityTesting"))
                    .AddCallHandler(new ExceptionInterceptor());
 
            IBusinessLayerClass1 bl1 = _container.Resolve<IBusinessLayerClass1>();
            int i = 0;
 
            //ODD Behaviour
            //Uncomment try to have good beavhior
            //try
            //{
                i = bl1.Exception2();           
            //}
            //catch (Exception ex)
            //{
            //    Console.WriteLine(":->" + ex.GetType());
            //}

            Console.WriteLine(i);

            #endregion
   
   
2. BusinessLayerClass 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ExceptionInterceptionUnityConsole.Business;
using ExceptionInterceptionUnityConsole.Contracts;
using Microsoft.Practices.Unity;
namespace ExceptionInterceptionUnityConsole.Business
{
    public class BusinessLayerClass1 : IBusinessLayerClass1
    {
        private ITransactionContext _ctx;
        #region IBusinessLayerClass1 Members
        public ITransactionContext DataContext
        {
            get
            {
                return _ctx;
            }
            set
            {
                _ctx = value;
            }
        }
        public void BLClass1MethodA()
        {
            Console.WriteLine("BLClass1MethodA()");
        }
        public void BLClass1MethodB()
        {
            Console.WriteLine("BLClass1MethodB()");
        }
      
      
        //public void Exception1()
        //{
        //    throw new using ExceptionInterceptionUnityConsole.Business;.Exceptions.BLException();
        //}
        public int Exception2()
        {
            int a1=0;
            return 3 / a1;
        }
        #endregion
    }
}
3.Contracts
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.Unity;
namespace ExceptionInterceptionUnityConsole.Contracts
{
    public interface IBusinessLayerClass1
    {
        ITransactionContext DataContext { get; set; }
        void BLClass1MethodA();
        void BLClass1MethodB();
        //void Exception1();
        int Exception2();
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ExceptionInterceptionUnityConsole.Contracts
{
    public interface ITransactionContext
    {
        bool IsAlive();
        void Begin();
        void Commit();
        void RollBack();
    }
}
4.Interceptor
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.InterceptionExtension;
using Microsoft.Practices.Unity.Configuration;
namespace ExceptionInterceptionUnityConsole.Interceptors
{
    public class ExceptionInterceptor:ICallHandler
    {
        public ExceptionInterceptor() { }
        #region ICallHandler Members
        public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
        {
            IMethodReturn val;
            val = getNext()(input, getNext);
            if (val.Exception != null)
            {
                Console.WriteLine("Exception has been thrown");
                Console.WriteLine(val.Exception.Message.ToString());
                Console.WriteLine("[Exiting method: {0}]", input.MethodBase.Name);
                return input.CreateExceptionMethodReturn(val.Exception);
            }
            else
            {
                Console.WriteLine("[Exiting method: {0}]", input.MethodBase.Name);
                return val;
            }
           
        }
        public int Order
        {
            get
            {
               return 0 ;
            }
            set
            {
                throw new NotImplementedException();
            }
        }
        #endregion
    }
}

Again, if you prefer, or have the time, i can send the project to you
Thanx 
 
 
 


 
2009/6/9 ctavares <notifications@codeplex.com>

From: ctavares

Also, one minor thing. If you're not replacing the exception, you don't have to do "return input.CreateExceptionMessageReturn(val.Exception);", you can just return val. It's already set up with the thrown exception inside it.

 

Read the full discussion online.

To add a post to this discussion, reply to this email (unity@discussions.codeplex.com)

To start a new discussion for this project, email unity@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com