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.Collections.Generic;
33 using System.Diagnostics;
34 using System.Reflection;
36 using System.Runtime.InteropServices;
37 using System.Runtime.CompilerServices;
38 using System.Runtime.Serialization;
39 using System.Security.Permissions;
45 [ComDefaultInterface (typeof (_Exception))]
46 [ClassInterface (ClassInterfaceType.None)]
47 [StructLayout (LayoutKind.Sequential)]
49 public class Exception : ISerializable
51 public class Exception : ISerializable, _Exception
54 #pragma warning disable 169, 649
55 #region Sync with object-internals.h
56 /* Stores the IPs and the generic sharing infos
57 (vtable/MRGCTX) of the frames. */
59 Exception inner_exception;
60 internal string _message;
64 // formerly known as remote_stack_trace (see #425512):
65 string _remoteStackTraceString;
66 int remote_stack_index;
67 internal int hresult = -2146233088;
70 internal StackTrace[] captured_traces;
71 IntPtr[] native_trace_ips;
72 object dynamic_methods;
74 #pragma warning restore 169, 649
76 /* Don't add fields here, the runtime depends on the layout of subclasses */
82 public Exception (string message)
84 this._message = message;
87 protected Exception (SerializationInfo info, StreamingContext context)
90 throw new ArgumentNullException ("info");
92 class_name = info.GetString ("ClassName");
93 _message = info.GetString ("Message");
94 help_link = info.GetString ("HelpURL");
95 stack_trace = info.GetString ("StackTraceString");
96 _remoteStackTraceString = info.GetString ("RemoteStackTraceString");
97 remote_stack_index = info.GetInt32 ("RemoteStackIndex");
98 hresult = info.GetInt32 ("HResult");
99 source = info.GetString ("Source");
100 inner_exception = (Exception) info.GetValue ("InnerException", typeof (Exception));
103 _data = (IDictionary) info.GetValue ("Data", typeof (IDictionary));
104 } catch (SerializationException) {
105 // member did not exist in .NET 1.x
109 public Exception (string message, Exception innerException)
111 inner_exception = innerException;
112 this._message = message;
115 public Exception InnerException {
116 get { return inner_exception; }
119 public virtual string HelpLink {
120 get { return help_link; }
121 set { help_link = value; }
125 get { return hresult; }
126 protected set { hresult = value; }
129 internal void SetErrorCode(int hr)
134 internal void SetMessage (string s)
139 internal void SetStackTrace (string s)
146 if (class_name == null)
147 class_name = GetType ().ToString ();
152 public virtual string Message {
154 if (_message == null)
155 _message = string.Format (Locale.GetText ("Exception of type '{0}' was thrown."),
163 protected event EventHandler<SafeSerializationEventArgs> SerializeObjectState {
170 public virtual string Source {
172 if (source == null) {
173 StackTrace st = new StackTrace (this, true);
174 if (st.FrameCount > 0) {
175 StackFrame sf = st.GetFrame (0);
177 MethodBase method = sf.GetMethod ();
178 if (method != null) {
179 source = method.DeclaringType.Assembly.UnprotectedGetName ().Name;
185 // source can be null
194 public virtual string StackTrace {
196 if (stack_trace != null)
199 if (trace_ips == null)
203 StackTrace st = new StackTrace (this, 0, true);
204 return stack_trace = st.ToString ();
208 public MethodBase TargetSite {
210 StackTrace st = new StackTrace (this, true);
211 if (st.FrameCount > 0)
212 return st.GetFrame (0).GetMethod ();
218 public virtual IDictionary Data {
221 // default to empty dictionary
222 _data = new Dictionary<object, object> ();
228 public virtual Exception GetBaseException ()
230 Exception inner = inner_exception;
232 while (inner != null)
234 if (inner.InnerException != null)
235 inner = inner.InnerException;
243 [SecurityPermission (SecurityAction.LinkDemand, SerializationFormatter = true)]
244 public virtual void GetObjectData (SerializationInfo info, StreamingContext context)
247 throw new ArgumentNullException ("info");
249 info.AddValue ("ClassName", ClassName);
250 info.AddValue ("Message", _message);
251 info.AddValue ("InnerException", inner_exception);
252 info.AddValue ("HelpURL", help_link);
253 info.AddValue ("StackTraceString", StackTrace);
254 info.AddValue ("RemoteStackTraceString", _remoteStackTraceString);
255 info.AddValue ("RemoteStackIndex", remote_stack_index);
256 info.AddValue ("HResult", hresult);
257 info.AddValue ("Source", Source);
258 info.AddValue ("ExceptionMethod", null);
259 info.AddValue ("Data", _data, typeof (IDictionary));
262 public override string ToString ()
264 System.Text.StringBuilder result = new System.Text.StringBuilder (ClassName);
265 result.Append (": ").Append (Message);
267 if (null != _remoteStackTraceString)
268 result.Append (_remoteStackTraceString);
270 if (inner_exception != null)
272 result.Append (" ---> ").Append (inner_exception.ToString ());
273 result.Append (Environment.NewLine);
274 result.Append (Locale.GetText (" --- End of inner exception stack trace ---"));
277 if (StackTrace != null)
278 result.Append (Environment.NewLine).Append (StackTrace);
279 return result.ToString();
282 internal Exception FixRemotingException ()
284 string message = (0 == remote_stack_index) ?
285 Locale.GetText ("{0}{0}Server stack trace: {0}{1}{0}{0}Exception rethrown at [{2}]: {0}") :
286 Locale.GetText ("{1}{0}{0}Exception rethrown at [{2}]: {0}");
287 string tmp = String.Format (message, Environment.NewLine, StackTrace, remote_stack_index);
289 _remoteStackTraceString = tmp;
290 remote_stack_index++;
297 // For ExceptionDispatchInfo
298 internal void RestoreExceptionDispatchInfo (System.Runtime.ExceptionServices.ExceptionDispatchInfo exceptionDispatchInfo)
300 captured_traces = (StackTrace[]) exceptionDispatchInfo.BinaryStackTraceArray;
306 // The documentation states that this is available in 1.x,
307 // but it was not available (MemberRefing this would fail)
308 // and it states the signature is `override sealed', but the
309 // correct value is `newslot'
311 public new Type GetType ()
313 return base.GetType ();
316 internal enum ExceptionMessageKind
319 ThreadInterrupted = 2,
323 internal static String GetMessageFromNativeResources (ExceptionMessageKind kind)
326 case ExceptionMessageKind.ThreadAbort:
328 case ExceptionMessageKind.ThreadInterrupted:
330 case ExceptionMessageKind.OutOfMemory:
331 return "Out of memory";