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;
}