Skip to content

exception.StackTrace is truncated when using Interceptors #3

@ENikS

Description

@ENikS

@cshung wrote:

Consider the following code snippet

using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.InterceptionExtension;
using System;
using System.Collections.Generic;

namespace ConsoleApplication1
{
public interface IService
{
void work();
}

   public class Service : IService
   {
       public void work() { a(); }
       private void a() { b(); }
       private void b() { c(); }
       private void c() { throw new NotImplementedException { }; ; }
   }

   public class Interceptor : IInterceptionBehavior
   {
       public bool WillExecute { get { return true; } }
       public IEnumerable<Type> GetRequiredInterfaces() { return Type.EmptyTypes; }

       public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
       {
           Console.WriteLine("Enter invoke");
           var result = getNext()(input, getNext);
           Console.WriteLine("Exit invoke");
           return result;
       }
   }

   public class UnityStackTraceMain
   {
       static void Main(string[] args)
       {
           var container = new UnityContainer { };
           container.AddNewExtension<Interception>();
           //container.AddNewExtension<AppContainerExtension>();

           container.RegisterType<IService, Service>(
               new ContainerControlledLifetimeManager(),
               new Interceptor<InterfaceInterceptor>(),
               new InterceptionBehavior<Interceptor>());

           try
           {
               container.Resolve<IService>().work();
           }
           catch (System.Exception ex)
           {
               Console.WriteLine(ex.ToString());
               Console.WriteLine(ex.InnerException);
           }

           Console.ReadLine();
       }
   }

}

We expect the ex.ToString() has the frames a(), b() and c(), but instead, it only have the dynamic generated function.

The root cause of this is because the exception is caught and thrown again. .NET does not preserve the stack trace in the exception in that case and is clearly documented.

The proper way to fix this is to wrap the exception. In order to make existing code work with the fix. I wrap the exception with the same type and same message, that should allow most code to work with it.

Since the interceptor code is not available in this repo, I created the pull request to fix this in CodePlex instead.

https://unity.codeplex.com/SourceControl/network/forks/cshung/unity/contribution/8726

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions