//
using System.Collections;
+using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Text;
namespace System
{
[Serializable]
- [ClassInterface (ClassInterfaceType.AutoDual)]
- public class Exception : ISerializable
-#if NET_2_0
- , _Exception
+ [ComVisible(true)]
+ [ComDefaultInterface (typeof (_Exception))]
+ [ClassInterface (ClassInterfaceType.None)]
+ [StructLayout (LayoutKind.Sequential)]
+#if MOBILE
+ public class Exception : ISerializable
+#else
+ public class Exception : ISerializable, _Exception
#endif
{
+#pragma warning disable 169, 649
+ #region Sync with object-internals.h
+ /* Stores the IPs and the generic sharing infos
+ (vtable/MRGCTX) of the frames. */
IntPtr [] trace_ips;
Exception inner_exception;
- internal string message;
+ internal string _message;
string help_link;
string class_name;
string stack_trace;
- string remote_stack_trace;
+ // formerly known as remote_stack_trace (see #425512):
+ string _remoteStackTraceString;
int remote_stack_index;
- internal int hresult = unchecked ((int)0x80004005);
+ internal int hresult = -2146233088;
string source;
+ IDictionary _data;
+ internal StackTrace[] captured_traces;
+ IntPtr[] native_trace_ips;
+ object dynamic_methods;
+ #endregion
+#pragma warning restore 169, 649
+
+ /* Don't add fields here, the runtime depends on the layout of subclasses */
public Exception ()
{
}
- public Exception (string msg)
+ public Exception (string message)
{
- message = msg;
+ this._message = message;
}
- protected Exception (SerializationInfo info, StreamingContext sc)
+ protected Exception (SerializationInfo info, StreamingContext context)
{
if (info == null)
throw new ArgumentNullException ("info");
class_name = info.GetString ("ClassName");
- message = info.GetString ("Message");
+ _message = info.GetString ("Message");
help_link = info.GetString ("HelpURL");
stack_trace = info.GetString ("StackTraceString");
- remote_stack_trace = info.GetString ("RemoteStackTraceString");
+ _remoteStackTraceString = info.GetString ("RemoteStackTraceString");
remote_stack_index = info.GetInt32 ("RemoteStackIndex");
hresult = info.GetInt32 ("HResult");
source = info.GetString ("Source");
inner_exception = (Exception) info.GetValue ("InnerException", typeof (Exception));
+
+ try {
+ _data = (IDictionary) info.GetValue ("Data", typeof (IDictionary));
+ } catch (SerializationException) {
+ // member did not exist in .NET 1.x
+ }
}
- public Exception (string msg, Exception e)
+ public Exception (string message, Exception innerException)
{
- inner_exception = e;
- message = msg;
+ inner_exception = innerException;
+ this._message = message;
}
public Exception InnerException {
set { help_link = value; }
}
- protected int HResult {
+ public int HResult {
get { return hresult; }
- set { hresult = value; }
+ protected set { hresult = value; }
+ }
+
+ internal void SetErrorCode(int hr)
+ {
+ HResult = hr;
}
internal void SetMessage (string s)
{
- message = s;
+ _message = s;
}
internal void SetStackTrace (string s)
stack_trace = s;
}
+ string ClassName {
+ get {
+ if (class_name == null)
+ class_name = GetType ().ToString ();
+ return class_name;
+ }
+ }
+
public virtual string Message {
get {
- if (message == null)
- message = string.Format (Locale.GetText ("Exception of type {0} was thrown."), GetType ().ToString());
+ if (_message == null)
+ _message = string.Format (Locale.GetText ("Exception of type '{0}' was thrown."),
+ ClassName);
- return message;
+ return _message;
+ }
+ }
+
+ [MonoTODO]
+ protected event EventHandler<SafeSerializationEventArgs> SerializeObjectState {
+ add {
+ }
+ remove {
}
}
public virtual string Source {
-#if ONLY_1_1
- [ReflectionPermission (SecurityAction.Assert, TypeInformation = true)]
-#endif
get {
if (source == null) {
StackTrace st = new StackTrace (this, true);
}
}
- // source can be null
+ // source can be null
return source;
}
public virtual string StackTrace {
get {
- if (stack_trace == null) {
- if (trace_ips == null)
- /* Not thrown yet */
- return null;
-
- StackTrace st = new StackTrace (this, 0, true, true);
-
- StringBuilder sb = new StringBuilder ();
-
- string newline = String.Format ("{0} {1} ", Environment.NewLine, Locale.GetText ("at"));
- string unknown = Locale.GetText ("<unknown method>");
-
- for (int i = 0; i < st.FrameCount; i++) {
- StackFrame frame = st.GetFrame (i);
- if (i == 0)
- sb.AppendFormat (" {0} ", Locale.GetText ("at"));
- else
- sb.Append (newline);
-
- if (frame.GetMethod () == null) {
- string internal_name = frame.GetInternalMethodName ();
- if (internal_name != null)
- sb.Append (internal_name);
- else
- sb.AppendFormat ("<0x{0:x5}> {1}", frame.GetNativeOffset (), unknown);
- } else {
- sb.Append (GetFullNameForStackTrace (frame.GetMethod ()));
-
- if (frame.GetILOffset () == -1)
- sb.AppendFormat (" <0x{0:x5}> ", frame.GetNativeOffset ());
- else
- sb.AppendFormat (" [0x{0:x5}] ", frame.GetILOffset ());
-
- string fileName = frame.GetFileName ();
- if (fileName != null)
- sb.AppendFormat ("in {0}:{1} ", fileName, frame.GetFileLineNumber ());
- }
- }
- stack_trace = sb.ToString ();
- }
+ if (stack_trace != null)
+ return stack_trace;
+
+ if (trace_ips == null)
+ /* Not thrown yet */
+ return null;
- return stack_trace;
+ StackTrace st = new StackTrace (this, 0, true);
+ return stack_trace = st.ToString ();
}
}
public MethodBase TargetSite {
-#if ONLY_1_1
- [ReflectionPermission (SecurityAction.Demand, TypeInformation = true)]
-#endif
get {
StackTrace st = new StackTrace (this, true);
if (st.FrameCount > 0)
}
}
-#if NET_2_0
- private IDictionary _data;
-
public virtual IDictionary Data {
get {
if (_data == null) {
// default to empty dictionary
- _data = (IDictionary) new Hashtable ();
+ _data = new Dictionary<object, object> ();
}
return _data;
}
}
-#endif
public virtual Exception GetBaseException ()
{
return this;
}
-#if ONLY_1_1
- [ReflectionPermission (SecurityAction.Assert, TypeInformation = true)]
-#endif
[SecurityPermission (SecurityAction.LinkDemand, SerializationFormatter = true)]
public virtual void GetObjectData (SerializationInfo info, StreamingContext context)
{
if (info == null)
throw new ArgumentNullException ("info");
- if (class_name == null)
- class_name = GetType ().FullName;
-
- info.AddValue ("ClassName", class_name);
- info.AddValue ("Message", message);
+ info.AddValue ("ClassName", ClassName);
+ info.AddValue ("Message", _message);
info.AddValue ("InnerException", inner_exception);
info.AddValue ("HelpURL", help_link);
info.AddValue ("StackTraceString", StackTrace);
- info.AddValue ("RemoteStackTraceString", remote_stack_trace);
+ info.AddValue ("RemoteStackTraceString", _remoteStackTraceString);
info.AddValue ("RemoteStackIndex", remote_stack_index);
info.AddValue ("HResult", hresult);
info.AddValue ("Source", Source);
info.AddValue ("ExceptionMethod", null);
+ info.AddValue ("Data", _data, typeof (IDictionary));
}
-#if ONLY_1_1
- [ReflectionPermission (SecurityAction.Assert, TypeInformation = true)]
-#endif
public override string ToString ()
{
- System.Text.StringBuilder result = new System.Text.StringBuilder (this.GetType ().FullName);
+ System.Text.StringBuilder result = new System.Text.StringBuilder (ClassName);
result.Append (": ").Append (Message);
- if (null != remote_stack_trace)
- result.Append (remote_stack_trace);
+ if (null != _remoteStackTraceString)
+ result.Append (_remoteStackTraceString);
if (inner_exception != null)
{
result.Append (" ---> ").Append (inner_exception.ToString ());
- result.Append (Locale.GetText ("--- End of inner exception stack trace ---"));
result.Append (Environment.NewLine);
+ result.Append (Locale.GetText (" --- End of inner exception stack trace ---"));
}
if (StackTrace != null)
Locale.GetText ("{1}{0}{0}Exception rethrown at [{2}]: {0}");
string tmp = String.Format (message, Environment.NewLine, StackTrace, remote_stack_index);
- remote_stack_trace = tmp;
+ _remoteStackTraceString = tmp;
remote_stack_index++;
stack_trace = null;
return this;
}
- internal string GetFullNameForStackTrace (MethodBase mi)
+ // For ExceptionDispatchInfo
+ internal void RestoreExceptionDispatchInfo (System.Runtime.ExceptionServices.ExceptionDispatchInfo exceptionDispatchInfo)
{
- string parms = String.Empty;
- ParameterInfo[] p = mi.GetParameters ();
- for (int i = 0; i < p.Length; ++i) {
- if (i > 0)
- parms = parms + ", ";
- string paramName = (p [i].Name == null) ? String.Empty : (" " + p [i].Name);
- Type pt = p[i].ParameterType;
- if (pt.IsClass && pt.Namespace != String.Empty)
- parms = parms + pt.Namespace + "." + pt.Name + paramName;
- else
- parms = parms + pt.Name + paramName;
- }
+ captured_traces = (StackTrace[]) exceptionDispatchInfo.BinaryStackTraceArray;
+ trace_ips = null;
+ stack_trace = null;
+ }
- string generic = String.Empty;
-#if NET_2_0 || BOOTSTRAP_NET_2_0
- if (mi.IsGenericMethod) {
- Type[] gen_params = mi.GetGenericArguments ();
- generic = "[";
- for (int j = 0; j < gen_params.Length; j++) {
- if (j > 0)
- generic += ",";
- generic += gen_params [j].Name;
- }
- generic += "]";
+ //
+ // The documentation states that this is available in 1.x,
+ // but it was not available (MemberRefing this would fail)
+ // and it states the signature is `override sealed', but the
+ // correct value is `newslot'
+ //
+ public new Type GetType ()
+ {
+ return base.GetType ();
+ }
+
+ internal enum ExceptionMessageKind
+ {
+ ThreadAbort = 1,
+ ThreadInterrupted = 2,
+ OutOfMemory = 3
+ }
+
+ internal static String GetMessageFromNativeResources (ExceptionMessageKind kind)
+ {
+ switch (kind) {
+ case ExceptionMessageKind.ThreadAbort:
+ return "";
+ case ExceptionMessageKind.ThreadInterrupted:
+ return "";
+ case ExceptionMessageKind.OutOfMemory:
+ return "Out of memory";
}
-#endif
- return mi.DeclaringType.ToString () + "." + mi.Name + generic + " (" + parms + ")";
- }
+ return "";
+ }
}
}