2004-12-06 Ben Maurer <bmaurer@ximian.com>
[mono.git] / mcs / class / corlib / System / Exception.cs
1 //
2 // System.Exception.cs
3 //
4 // Author:
5 //   Miguel de Icaza (miguel@ximian.com)
6 //   Patrik Torstensson
7 //
8 // (C) Ximian, Inc.  http://www.ximian.com
9 //
10
11 //
12 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
13 //
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
21 // 
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
24 // 
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 //
33
34 using System.Runtime.InteropServices;
35 using System.Runtime.Serialization;
36 using System.Reflection;
37 using System.Diagnostics;
38
39 namespace System
40 {
41         [Serializable]
42         [ClassInterface (ClassInterfaceType.AutoDual)]
43         public class Exception : ISerializable 
44 #if NET_2_0
45         , _Exception
46 #endif
47         {
48                 IntPtr [] trace_ips;
49                 Exception inner_exception;
50                 string message;
51                 string help_link;
52                 string class_name;
53                 string stack_trace;
54                 string remote_stack_trace;
55                 int remote_stack_index;
56                 int hresult = unchecked ((int)0x80004005);
57                 string source;
58
59                 public Exception ()
60                 {
61                 }
62
63                 public Exception (string msg)
64                 {
65                         message = msg;
66                 }
67
68                 protected Exception (SerializationInfo info, StreamingContext sc)
69                 {
70                         if (info == null)
71                                 throw new ArgumentNullException ("info");
72
73                         class_name          = info.GetString ("ClassName");
74                         message             = info.GetString ("Message");
75                         help_link           = info.GetString ("HelpURL");
76                         stack_trace         = info.GetString ("StackTraceString");
77                         remote_stack_trace  = info.GetString ("RemoteStackTraceString");
78                         remote_stack_index  = info.GetInt32  ("RemoteStackIndex");
79                         hresult             = info.GetInt32  ("HResult");
80                         source              = info.GetString ("Source");
81                         inner_exception     = (Exception) info.GetValue ("InnerException", typeof (Exception));
82                 }
83
84                 public Exception (string msg, Exception e)
85                 {
86                         inner_exception = e;
87                         message = msg;
88                 }
89
90                 public Exception InnerException {
91                         get { return inner_exception; }
92                 }
93
94                 public virtual string HelpLink {
95                         get { return help_link; }
96                         set { help_link = value; }
97                 }
98
99                 protected int HResult {
100                         get { return hresult; }
101                         set { hresult = value; }
102                 }
103
104                 internal void SetMessage (string s)
105                 {
106                         message = s;
107                 }
108
109                 internal void SetStackTrace (string s)
110                 {
111                         stack_trace = s;
112                 }
113
114                 public virtual string Message {
115                         get {
116                                 if (message == null)
117                                         message = string.Format (Locale.GetText ("Exception of type {0} was thrown."), GetType ().ToString());
118
119                                 return message;
120                         }
121                 }
122
123                 public virtual string Source {
124                         get {
125                                 if (source == null) {
126                                         StackTrace st = new StackTrace (this, true);
127                                         if (st.FrameCount > 0) {
128                                                 StackFrame sf = st.GetFrame (0);
129                                                 if (st != null) {
130                                                         MethodBase method = sf.GetMethod ();
131                                                         if (method != null) {
132                                                                 source = method.DeclaringType.Assembly.GetName ().Name;
133                                                         }
134                                                 }
135                                         }
136                                 }
137
138                                 // source can be null
139                                 return source;
140                         }
141
142                         set {
143                                 source = value;
144                         }
145                 }
146
147                 public virtual string StackTrace {
148                         get {
149                                 return stack_trace;
150                         }
151                 }
152
153                 public MethodBase TargetSite {
154                         get {
155                                 StackTrace st = new StackTrace (this, true);
156                                 if (st.FrameCount > 0)
157                                         return st.GetFrame (0).GetMethod ();
158                                 
159                                 return null;
160                         }
161                 }
162
163                 public virtual Exception GetBaseException ()
164                 {
165                         Exception inner = inner_exception;
166                                 
167                         while (inner != null)
168                         {
169                                 if (inner.InnerException != null)
170                                         inner = inner.InnerException;
171                                 else
172                                         return inner;
173                         }
174
175                         return this;
176                 }
177
178                 public virtual void GetObjectData (SerializationInfo info, StreamingContext context)
179                 {
180                         if (class_name == null)
181                                 class_name = GetType ().FullName;
182                         
183                         info.AddValue ("ClassName", class_name);
184                         info.AddValue ("Message", message);
185                         info.AddValue ("InnerException", inner_exception);
186                         info.AddValue ("HelpURL", help_link);
187                         info.AddValue ("StackTraceString", stack_trace);
188                         info.AddValue ("RemoteStackTraceString", remote_stack_trace);
189                         info.AddValue ("RemoteStackIndex", remote_stack_index);
190                         info.AddValue ("HResult", hresult);
191                         info.AddValue ("Source", Source);
192                         info.AddValue ("ExceptionMethod", null);
193                 }
194
195                 public override string ToString ()
196                 {
197                         System.Text.StringBuilder result = new System.Text.StringBuilder (this.GetType ().FullName);
198                         result.Append (": ").Append (Message);
199
200                         if (null != remote_stack_trace)
201                                 result.Append (remote_stack_trace);
202                                 
203                         if (inner_exception != null) 
204                         {
205                                 result.Append (" ---> ").Append (inner_exception.ToString ());
206                                 result.Append (Locale.GetText ("--- End of inner exception stack trace ---"));
207                                 result.Append (Environment.NewLine);
208                         }
209
210                         if (stack_trace != null)
211                                 result.Append (Environment.NewLine).Append (stack_trace);
212                         return result.ToString();
213                 }
214
215                 internal Exception FixRemotingException ()
216                 {
217                         string message = (0 == remote_stack_index) ?
218                                 Locale.GetText ("{0}{0}Server stack trace: {0}{1}{0}{0}Exception rethrown at [{2}]: {0}") :
219                                 Locale.GetText ("{1}{0}{0}Exception rethrown at [{2}]: {0}");
220                         string tmp = String.Format (message, Environment.NewLine, StackTrace, remote_stack_index);
221
222                         remote_stack_trace = tmp;
223                         remote_stack_index++;
224
225                         stack_trace = null;
226
227                         return this;
228                 }
229         }
230 }