Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Original stack trace is lost at Interpreter.TryInterpretAndUnwrapContainerException #250

Closed
ryoasai opened this issue Mar 29, 2020 · 1 comment
Milestone

Comments

@ryoasai
Copy link

ryoasai commented Mar 29, 2020

I had a trouble while debugging a thread safety problem of my code.

When executing all test cases, one of my test case failed with the following exception:

System.NullReferenceException : Object reference not set to an instance of an object.
   at DryIoc.Interpreter.TryInterpretAndUnwrapContainerException(IResolverContext r, Expression expr, Boolean useFec, Object& result) in C:\projects\dryioc-qt8fa\src\DryIoc\Container.cs:line 2709
   at DryIoc.Factory.ApplyReuse(Expression serviceExpr, Request request) in C:\projects\dryioc-qt8fa\src\DryIoc\Container.cs:line 9484
   at DryIoc.Factory.GetExpressionOrDefault(Request request) in C:\projects\dryioc-qt8fa\src\DryIoc\Container.cs:line 9440
   at DryIoc.Container.ResolveAndCache(Int32 serviceTypeHash, Type serviceType, IfUnresolved ifUnresolved) in C:\projects\dryioc-qt8fa\src\DryIoc\Container.cs:line 388
   at DryIoc.Container.DryIoc.IResolver.Resolve(Type serviceType, IfUnresolved ifUnresolved) in C:\projects\dryioc-qt8fa\src\DryIoc\Container.cs:line 353
   at DryIoc.Resolver.Resolve(IResolver resolver, Type serviceType) in C:\projects\dryioc-qt8fa\src\DryIoc\Container.cs:line 7325
   at Prism.DryIoc.Ioc.DryIocContainerExtension.Resolve(Type type)
   at Prism.Ioc.IContainerProviderExtensions.Resolve[T](IContainerProvider provider)

But when I execute the failed test case, it somehow passed.

At first I had a fooled impression that the problem is in DryIoc code, but after digging into the problem, I found the NullRefereneException was thrown in Dictionary class. It was my fault that I was using the plain Dictionary class as a cache. Replacing it with CuncurrentDictionary solved the problem.

That's ok but a annoyingly that the original exception stack trace is lost at the following code:

          public static bool TryInterpretAndUnwrapContainerException(
            IResolverContext r, Expression expr, bool useFec, out object result)
        {
            try
            {
                return Interpreter.TryInterpret(r, expr, FactoryDelegateCompiler.ResolverContextParamExpr, r, null, useFec, out result);
            }
            catch (TargetInvocationException tex) when (tex.InnerException != null)
            {
                // restore the original excpetion which is expected by the consumer code
                throw tex.InnerException; // Original stack trace is lost here, make it hard to debug.
            }
        }

So it's not a DryIoC's bug per se but I think it's better that it will report the original stack trace to help debugging.

There seems to be a technique to keep the original stack trace, for example:

https://stackoverflow.com/questions/57383/how-to-rethrow-innerexception-without-losing-stack-trace-in-c

Can you take a look at this problem?
I'm currently using v4.1.3.

@dadhi
Copy link
Owner

dadhi commented Mar 29, 2020

@ryoasai This is a good catch!
I will add the fix into the next minor version.

@dadhi dadhi added this to the v4.1.4 milestone Mar 29, 2020
@dadhi dadhi closed this as completed in 41eb818 Mar 30, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants