5 // Miguel de Icaza (miguel@ximian.com)
8 // (C) Ximian, Inc. http://www.ximian.com
9 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 using System
.Collections
;
32 using System
.Diagnostics
;
33 using System
.Reflection
;
35 using System
.Runtime
.InteropServices
;
36 using System
.Runtime
.CompilerServices
;
37 using System
.Runtime
.Serialization
;
38 using System
.Security
.Permissions
;
44 [ComDefaultInterface (typeof (_Exception
))]
45 [ClassInterface (ClassInterfaceType
.None
)]
46 public class Exception
: ISerializable
, _Exception
48 #pragma warning disable 169, 649
49 #region Sync with object-internals.h
50 /* Stores the IPs and the generic sharing infos
51 (vtable/MRGCTX) of the frames. */
53 Exception inner_exception
;
54 internal string message
;
58 // formerly known as remote_stack_trace (see #425512):
59 string _remoteStackTraceString
;
60 int remote_stack_index
;
61 internal int hresult
= -2146233088;
65 #pragma warning restore 169, 649
68 protected event EventHandler
<SafeSerializationEventArgs
> SerializeObjectState
{
70 add { throw new NotImplementedException (); }
72 remove { throw new NotImplementedException (); }
80 public Exception (string message
)
82 this.message
= message
;
85 protected Exception (SerializationInfo info
, StreamingContext context
)
88 throw new ArgumentNullException ("info");
90 class_name
= info
.GetString ("ClassName");
91 message
= info
.GetString ("Message");
92 help_link
= info
.GetString ("HelpURL");
93 stack_trace
= info
.GetString ("StackTraceString");
94 _remoteStackTraceString
= info
.GetString ("RemoteStackTraceString");
95 remote_stack_index
= info
.GetInt32 ("RemoteStackIndex");
96 hresult
= info
.GetInt32 ("HResult");
97 source
= info
.GetString ("Source");
98 inner_exception
= (Exception
) info
.GetValue ("InnerException", typeof (Exception
));
101 _data
= (IDictionary
) info
.GetValue ("Data", typeof (IDictionary
));
102 } catch (SerializationException
) {
103 // member did not exist in .NET 1.x
107 public Exception (string message
, Exception innerException
)
109 inner_exception
= innerException
;
110 this.message
= message
;
113 public Exception InnerException
{
114 get { return inner_exception; }
117 public virtual string HelpLink
{
118 get { return help_link; }
119 set { help_link = value; }
122 protected int HResult
{
123 get { return hresult; }
124 set { hresult = value; }
127 internal void SetMessage (string s
)
132 internal void SetStackTrace (string s
)
139 if (class_name
== null)
140 class_name
= GetType ().ToString ();
145 public virtual string Message
{
148 message
= string.Format (Locale
.GetText ("Exception of type '{0}' was thrown."),
155 public virtual string Source
{
157 if (source
== null) {
158 StackTrace st
= new StackTrace (this, true);
159 if (st
.FrameCount
> 0) {
160 StackFrame sf
= st
.GetFrame (0);
162 MethodBase method
= sf
.GetMethod ();
163 if (method
!= null) {
164 source
= method
.DeclaringType
.Assembly
.UnprotectedGetName ().Name
;
170 // source can be null
179 public virtual string StackTrace
{
181 if (stack_trace
== null) {
182 if (trace_ips
== null)
186 StackTrace st
= new StackTrace (this, 0, true, true);
188 StringBuilder sb
= new StringBuilder ();
190 string newline
= String
.Format ("{0} {1} ", Environment
.NewLine
, Locale
.GetText ("at"));
191 string unknown
= Locale
.GetText ("<unknown method>");
193 for (int i
= 0; i
< st
.FrameCount
; i
++) {
194 StackFrame frame
= st
.GetFrame (i
);
196 sb
.AppendFormat (" {0} ", Locale
.GetText ("at"));
200 if (frame
.GetMethod () == null) {
201 string internal_name
= frame
.GetInternalMethodName ();
202 if (internal_name
!= null)
203 sb
.Append (internal_name
);
205 sb
.AppendFormat ("<0x{0:x5}> {1}", frame
.GetNativeOffset (), unknown
);
207 GetFullNameForStackTrace (sb
, frame
.GetMethod ());
209 if (frame
.GetILOffset () == -1)
210 sb
.AppendFormat (" <0x{0:x5}> ", frame
.GetNativeOffset ());
212 sb
.AppendFormat (" [0x{0:x5}] ", frame
.GetILOffset ());
214 sb
.AppendFormat ("in {0}:{1} ", frame
.GetSecureFileName (),
215 frame
.GetFileLineNumber ());
218 stack_trace
= sb
.ToString ();
225 public MethodBase TargetSite
{
227 StackTrace st
= new StackTrace (this, true);
228 if (st
.FrameCount
> 0)
229 return st
.GetFrame (0).GetMethod ();
235 public virtual IDictionary Data
{
238 // default to empty dictionary
239 _data
= (IDictionary
) new Hashtable ();
245 public virtual Exception
GetBaseException ()
247 Exception inner
= inner_exception
;
249 while (inner
!= null)
251 if (inner
.InnerException
!= null)
252 inner
= inner
.InnerException
;
260 [SecurityPermission (SecurityAction
.LinkDemand
, SerializationFormatter
= true)]
261 public virtual void GetObjectData (SerializationInfo info
, StreamingContext context
)
264 throw new ArgumentNullException ("info");
266 info
.AddValue ("ClassName", ClassName
);
267 info
.AddValue ("Message", message
);
268 info
.AddValue ("InnerException", inner_exception
);
269 info
.AddValue ("HelpURL", help_link
);
270 info
.AddValue ("StackTraceString", StackTrace
);
271 info
.AddValue ("RemoteStackTraceString", _remoteStackTraceString
);
272 info
.AddValue ("RemoteStackIndex", remote_stack_index
);
273 info
.AddValue ("HResult", hresult
);
275 info
.AddValue ("Source", Source
);
277 info
.AddValue ("Source", null);
279 info
.AddValue ("ExceptionMethod", null);
280 info
.AddValue ("Data", _data
, typeof (IDictionary
));
283 public override string ToString ()
285 System
.Text
.StringBuilder result
= new System
.Text
.StringBuilder (ClassName
);
286 result
.Append (": ").Append (Message
);
288 if (null != _remoteStackTraceString
)
289 result
.Append (_remoteStackTraceString
);
291 if (inner_exception
!= null)
293 result
.Append (" ---> ").Append (inner_exception
.ToString ());
294 result
.Append (Environment
.NewLine
);
295 result
.Append (Locale
.GetText (" --- End of inner exception stack trace ---"));
298 if (StackTrace
!= null)
299 result
.Append (Environment
.NewLine
).Append (StackTrace
);
300 return result
.ToString();
303 internal Exception
FixRemotingException ()
305 string message
= (0 == remote_stack_index
) ?
306 Locale
.GetText ("{0}{0}Server stack trace: {0}{1}{0}{0}Exception rethrown at [{2}]: {0}") :
307 Locale
.GetText ("{1}{0}{0}Exception rethrown at [{2}]: {0}");
308 string tmp
= String
.Format (message
, Environment
.NewLine
, StackTrace
, remote_stack_index
);
310 _remoteStackTraceString
= tmp
;
311 remote_stack_index
++;
318 internal void GetFullNameForStackTrace (StringBuilder sb
, MethodBase mi
)
320 ParameterInfo
[] p
= mi
.GetParameters ();
321 sb
.Append (mi
.DeclaringType
.ToString ());
325 if (mi
.IsGenericMethod
) {
326 Type
[] gen_params
= mi
.GetGenericArguments ();
328 for (int j
= 0; j
< gen_params
.Length
; j
++) {
331 sb
.Append (gen_params
[j
].Name
);
337 for (int i
= 0; i
< p
.Length
; ++i
) {
340 Type pt
= p
[i
].ParameterType
;
341 if (pt
.IsClass
&& pt
.Namespace
!= String
.Empty
) {
342 sb
.Append (pt
.Namespace
);
346 if (p
[i
].Name
!= null) {
348 sb
.Append (p
[i
].Name
);
355 // The documentation states that this is available in 1.x,
356 // but it was not available (MemberRefing this would fail)
357 // and it states the signature is `override sealed', but the
358 // correct value is `newslot'
360 public new Type
GetType ()
362 return base.GetType ();