// // Copyright (C) 2004-2011 by Autodesk, Inc. // // This library is free software; you can redistribute it and/or // modify it under the terms of version 2.1 of the GNU Lesser // General Public License as published by the Free Software Foundation. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // using System; /// /// ManagedException is the exception class from which the root of unmanaged exception derive /// This class, deriving from .NET Exception, allows to use the most common properties of /// the Exception class on exceptions wrapping unmanaged MgException classes. The implementation /// of these properties relies on the equivalent MgException methods. /// /// Although this class does not wrap any unmanaged class, it still holds a C++ pointer to /// the MgException that derives from it. /// namespace OSGeo.MapGuide { [Serializable] public class ManagedException : Exception { private bool mIsWrapper; private string mMessage; private string mStackTrace; public ManagedException() { mIsWrapper = true; mMessage = string.Empty; mStackTrace = string.Empty; } protected ManagedException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { mIsWrapper = false; mMessage = info.GetString("ManagedException.Message"); mStackTrace = info.GetString("ManagedException.StackTrace"); } public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { base.GetObjectData(info, context); info.AddValue("ManagedException.Message", Message); info.AddValue("ManagedException.StackTrace", StackTrace); } public override string Message { get { return mIsWrapper ? ((MgException)this).GetExceptionMessage() : mMessage; } } public override string StackTrace { get { if (mIsWrapper) { //Some cosmetic cleaning of the C++ stack trace to better line up with the .net one string[] mgStackTrace = ((MgException)this).GetStackTrace().Split(new string[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries); //This currently looks like the following if we re-join: // // at- // at- // at- // //The "-" being a leftover, so replace "at-" with "at" as well after re-joining. //The reason we don't blindly replace "-" in the C++ stack is because we don't want to scramble any physical path //that would also contain a "-" string sanitizedStack = (" at" + string.Join(Environment.NewLine + " at", mgStackTrace)).Replace("at-", "at"); return string.Format("{0}{1} ==== [C++ <-> .net] ===={1}{2}", sanitizedStack, Environment.NewLine, base.StackTrace); } else { return mStackTrace; } } } public override string ToString() { string className = this.GetType().ToString(); return string.Format("{0}: {1}{2}{3}", className, this.Message, Environment.NewLine, this.StackTrace); } public virtual void Dispose() { //implemented by derived classes } } }