Skip to content

EndpointResolverExtensions-SelectOne trashes exception stack trace #376

@CornedBee

Description

@CornedBee
        public static T SelectOne<T>(this IEndpointResolver resolver, Func<AmqpTcpEndpoint, T> selector)
        {
            var t = default(T);
            Exception exception = null;
            foreach(var ep in resolver.All())
            {
                try
                {
                    // ...
                }
                catch (Exception e)
                {
                    exception = e;
                }
            }

            if(Object.Equals(t, default(T)) && exception != null)
            {
                throw exception;
            }

            return t;
    }

Here, inside the loop the code captures exceptions from attempts to connect to the endpoints. It remembers the last one, and at the end, if it didn't get a successful result, it rethrows this last exception.

However, in doing so, it trashes the stack trace of the exception, making debugging the underlying problem hard or impossible. (In my particular case, I'm getting a TypeInitializerException complaining that it can't initialize Interop.Http - but RabbitMQ has, according to my decompiler, no direct or indirect dependency on System.Net.Http ...)

It should do one of two things:

Simple: It should rethrow the exception using the ExceptionDispatchInfo method:

ExceptionDispatchInfo.Capture(exception).Throw();

More complicated but better: it should capture all exceptions and wrap them in an AggregateException:

        public static T SelectOne<T>(this IEndpointResolver resolver, Func<AmqpTcpEndpoint, T> selector)
        {
            var t = default(T);
            var exceptions = new List<Exception>();
            foreach(var ep in resolver.All())
            {
                try
                {
                    // ...
                }
                catch (Exception e)
                {
                    exceptions.Add(e);
                }
            }

            if(Object.Equals(t, default(T)) && exceptions.Count > 0)
            {
                throw new AggregateException(exceptions);
            }

            return t;
    }

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions