public List DescribeException()

in sdk/src/Core/Strategies/DefaultExceptionSerializationStrategy.cs [135:209]


        public List<ExceptionDescriptor> DescribeException(Exception e, IEnumerable<Subsegment> subsegments)
        {
            List<ExceptionDescriptor> result = new List<ExceptionDescriptor>();
           
            // First check if the exception has been described in subsegment
            ExceptionDescriptor ex = new ExceptionDescriptor();
            IEnumerable<ExceptionDescriptor> existingExceptionDescriptors = null;
            if (subsegments != null)
            {
                existingExceptionDescriptors = subsegments.Where(subsegment => subsegment.Cause != null && subsegment.Cause.IsExceptionAdded).SelectMany(subsegment => subsegment.Cause.ExceptionDescriptors);
            }

            ExceptionDescriptor existingDescriptor = null;
            if (existingExceptionDescriptors != null)
            {
                existingDescriptor = existingExceptionDescriptors.FirstOrDefault(descriptor => e.Equals(descriptor.Exception));
            }

            // While referencing exception from child, record id if exists or cause and return.
            if (existingDescriptor != null)
            {
                ex.Cause = existingDescriptor.Id != null ? existingDescriptor.Id : existingDescriptor.Cause;
                ex.Exception = existingDescriptor.Exception; // pass the exception of the cause so that this reference can be found if the same exception is thrown again
                ex.Id = null;  // setting this to null since, cause is already populated with reference to downstream exception
                result.Add(ex);
                return result;
            }

            // The exception is not described. Start describe it.
            ExceptionDescriptor curDescriptor = new ExceptionDescriptor();
            while (e != null)
            {
                curDescriptor.Exception = e;
                curDescriptor.Message = e.Message;
                curDescriptor.Type = e.GetType().Name;
                StackFrame[] frames = new StackTrace(e, true).GetFrames();
                if (frames != null && frames.Length > MaxStackFrameSize)
                {
                    curDescriptor.Truncated = frames.Length - MaxStackFrameSize;
                    curDescriptor.Stack = new StackFrame[MaxStackFrameSize];
                    Array.Copy(frames, curDescriptor.Stack, MaxStackFrameSize);
                }
                else
                {
                    curDescriptor.Stack = frames;
                }

                if (IsRemoteException(e))
                {
                    curDescriptor.Remote = true;
                }

                result.Add(curDescriptor);

                e = e.InnerException;
                if (e != null)
                {
                    // Inner exception alreay described
                    ExceptionDescriptor innerExceptionDescriptor = existingExceptionDescriptors != null ? existingExceptionDescriptors.FirstOrDefault(d => d.Exception.Equals(e)) : null;
                    if (innerExceptionDescriptor != null)
                    {
                        curDescriptor.Cause = innerExceptionDescriptor.Id;
                        e = null;
                    }
                    else
                    {
                        var newDescriptor = new ExceptionDescriptor();
                        curDescriptor.Cause = newDescriptor.Id;
                        curDescriptor = newDescriptor;
                    }
                }
            }

            return result;
        }