zhaolei
9 days ago 921de2254ff5712a44ed8575ee8efe34252f6603
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
using System.Collections.Specialized;
using System.Text;
 
namespace System
{
    /// <summary>
    /// 格式化异常方法扩展类
    /// </summary>
    public static class FormatExceptionExtensions
    {
        /// <summary>
        /// 格式化异常方法
        /// </summary>
        /// <param name="ex">Exception 实例</param>
        /// <param name="nv">Exception 附加信息集合</param>
        /// <returns></returns>
        public static string FormatException(this Exception ex, NameValueCollection? nv = null)
        {
            // Create StringBuilder to maintain publishing information.
            var strInfo = new StringBuilder();
            var additionalInfo = new NameValueCollection();
 
            #region Load the AdditionalInformation Collection with environment data.
            additionalInfo["TimeStamp"] = DateTime.Now.ToString();
            additionalInfo["MachineName"] = Environment.MachineName;
            additionalInfo["AppDomainName"] = AppDomain.CurrentDomain.FriendlyName;
            if (nv != null) additionalInfo.Add(nv);
            #endregion
 
            #region Record the contents of the AdditionalInfo collection
            // Record the contents of the AdditionalInfo collection.
            // Record General information.
            var generalSeparator = new string('*', 45);
            var subSeparator = new string('-', 45);
 
            strInfo.AppendFormat("General Information {0}{1}{0}Additional Info{0}", Environment.NewLine, generalSeparator);
            foreach (string? i in additionalInfo)
            {
                if (!string.IsNullOrEmpty(i)) strInfo.AppendFormat("{1}: {2}{0}", Environment.NewLine, i, additionalInfo.Get(i));
            }
            #endregion
 
            #region Loop through each exception class in the chain of exception objects
            // Loop through each exception class in the chain of exception objects.
            var currentException = ex;    // Temp variable to hold InnerException object during the loop.
            var intExceptionCount = 1;              // Count variable to track the number of exceptions in the chain.
            if (currentException is AggregateException ex1)
            {
                FormatInnerException(ref intExceptionCount, strInfo, generalSeparator, subSeparator, currentException);
                foreach (var innerEx in ex1.InnerExceptions) FormatInnerExceptionLoop(ref intExceptionCount, strInfo, generalSeparator, subSeparator, innerEx);
            }
            else FormatInnerExceptionLoop(ref intExceptionCount, strInfo, generalSeparator, subSeparator, currentException);
            #endregion
 
            strInfo.AppendLine();
            return strInfo.ToString();
        }
 
        private static void FormatInnerExceptionLoop(ref int intExceptionCount, StringBuilder strInfo, string generalSeparator, string subSeparator, Exception currentException)
        {
            Exception? ex = currentException;
 
            while (ex != null)
            {
                FormatInnerException(ref intExceptionCount, strInfo, generalSeparator, subSeparator, ex);
 
                // Reset the temp exception object and iterate the counter.
                ex = ex.InnerException;
            };
        }
 
        private static void FormatInnerException(ref int intExceptionCount, StringBuilder strInfo, string generalSeparator, string subSeparator, Exception currentException)
        {
            // Write title information for the exception object.
            strInfo.AppendFormat(null, "{0}{1}) Exception Information{0}{2}{0}", Environment.NewLine, intExceptionCount.ToString(), subSeparator);
            strInfo.AppendFormat(null, "Exception Type: {1}{0}", Environment.NewLine, currentException.GetType().FullName);
 
            #region Loop through the public properties of the exception object and record their value
            var aryPublicProperties = currentException.GetType().GetProperties();
            foreach (var p in aryPublicProperties)
            {
                // Do not log information for the InnerException or StackTrace. This information is
                // captured later in the process.
                if (p.Name != "InnerException" && p.Name != "StackTrace")
                {
                    var propertyValue = p.GetValue(currentException, null);
                    if (p.Name == "AdditionalInformation")
                    {
                        // Verify the collection is not null.
                        if (propertyValue != null)
                        {
                            #region Loop through the public properties of the exception object and record their value
                            // Loop through the public properties of the exception object and record their value.
                            // Cast the collection into a local variable.
                            var currentAdditionalInfo = propertyValue as NameValueCollection;
                            // Check if the collection contains values.
                            if (currentAdditionalInfo != null && currentAdditionalInfo.Count > 0)
                            {
                                strInfo.AppendFormat("AdditionalInformation{0}", Environment.NewLine);
                                // Loop through the collection adding the information to the string builder.
                                foreach (string? infoKey in currentAdditionalInfo)
                                {
                                    if (!string.IsNullOrEmpty(infoKey)) strInfo.AppendFormat("{1}: {2}{0}", Environment.NewLine, infoKey, currentAdditionalInfo[infoKey]);
                                }
                            }
                            #endregion
                        }
                    }
                    else
                    {
                        strInfo.AppendFormat("{1}: {2}{0}", Environment.NewLine, p.Name, propertyValue);
                    }
                }
            }
            #endregion
 
            #region Record the Exception StackTrace
            // Record the StackTrace with separate label.
            if (currentException.StackTrace != null)
            {
                strInfo.AppendFormat("{0}StackTrace Information{0}{1}{0}", Environment.NewLine, generalSeparator);
                strInfo.AppendFormat("{1}{0}", Environment.NewLine, currentException.StackTrace);
            }
            #endregion
 
            intExceptionCount++;
        }
    }
}