/// <summary>
        /// Handles instances of <see cref="System.Exception"/>.
        /// </summary>
        /// <param name="ex">The <see cref="System.Exception"/> exception class.</param>
        /// <param name="msg">The Soap Fault Detail message being created.</param>
        private static void HandleSystemException(System.Exception ex, ref SoapFaultDetail msg)
        {
            // Get the error message
            msg.Message = ex.Message;

            // Get the error number
            // .NET Exceptions are type-based, but each type has a unique HResult property, so we'll use this instead.
            msg.ExceptionNumber = Framework.ExceptionManagement.ExceptionManager.GetExHResult(ex);
        }
        /// <summary>
        /// Handles instances of <see cref="DacSqlException"/>.
        /// </summary>
        /// <param name="dex">The <see cref="DacSqlException"/> exception class.</param>
        /// <param name="msg">The Soap Fault Detail message being created.</param>
        private static void HandleDacException(DacSqlException dex, ref SoapFaultDetail msg)
        {
            // Get the error message and business process error number
            msg.Message         = dex.DetailedMessage;                      // not the 'Message' property
            msg.ExceptionNumber = dex.Number;

            // Now we need to add the database-specific info
            msg.Internal.Database = new SoapFaultDetailInternalDatabase();
            msg.Internal.Database.DatabaseServer = dex.DatabaseServer;
            msg.Internal.Database.Severity       = dex.Severity;
            msg.Internal.Database.Procedure      = dex.Procedure;
            msg.Internal.Database.LineNumber     = dex.LineNumber;
        }
        /// <summary>
        /// Creates a SoapFaultDetail message based upon the type of exception specified.
        /// </summary>
        /// <param name="ex">An exception containing information that is to be added to the SoapFaultDetail message.</param>
        /// <returns>The SoapFaultDetail message.</returns>
        public static XmlDocument CreateSoapFaultDetailMsg(System.Exception ex)
        {
            // Create the message
            SoapFaultDetail msg = new SoapFaultDetail();

            msg.Internal          = new SoapFaultDetailInternal();
            msg.Internal.Workflow = new SoapFaultDetailInternalWorkflow();

            // Set the Message, Exception Number and any other specific information
            BusinessProcessException bpex = ex as BusinessProcessException;
            DacSqlException          dex  = ex as DacSqlException;

            if (bpex != null)
            {
                // A workflow engine business process exception
                HandleBpException(bpex, ref msg);
            }
            else if (dex != null)
            {
                // A workflow engine data access component (DAC) exception
                HandleDacException(dex, ref msg);
            }
            else
            {
                // Handle it as a generic System.Exception
                HandleSystemException(ex, ref msg);
            }

            // Category
            switch (GetExceptionCategory(ex))
            {
            case WorkflowExceptionCategory.Error:
                msg.Category = SoapFaultDetailCategory.Error;
                break;

            case WorkflowExceptionCategory.Warning:
                msg.Category = SoapFaultDetailCategory.Warning;
                break;
            }

            // Exception Case Number
            msg.ExceptionCaseNumber = Framework.ExceptionManagement.ExceptionCaseNumber.Generate();

            // Exception Code
            msg.ExceptionCode = GetExceptionCode(ex);

            // Internal - Subsystem
            msg.Internal.Subsystem = Framework.Subsystem.WorkflowEngine.ToString();

            // Internal - Source
            msg.Internal.Source = ex.Source;

            // Internal - Stack Trace
            msg.Internal.StackTrace = ex.StackTrace.Trim();

            // Internal - Workflow - Workflow Server
            msg.Internal.Workflow.WorkflowServer = System.Environment.MachineName;

            // Internal - Workflow - Orchestration Name
            // Note: We are trying to get information about the orchestration in which the error occurred.
            //       However, if there is a messaging error (e.g. a message could not be delivered to a
            //       SOAP web service, the error will occur in an assembly in the BizTalk Engine, thus the
            //       top-level stack frame will be the BizTalk Engine and not the orchestration.
            //       Also, if there is an error in a component that is called from an Expression shape, the
            //       top-level stack frame will be the component and not the orchestration.
            //       Variable 'sf' will be null if the exception occurred outside of Orchestration
            StackFrame sf = Framework.ExceptionManagement.ExceptionManager.GetStackFrameByNamespace(ex, ".Orchestrations");

            if (sf == null)
            {
                msg.Internal.Workflow.OrchestrationName = "";
            }
            else
            {
                msg.Internal.Workflow.OrchestrationName = sf.GetMethod().DeclaringType.FullName;
            }

            // Serialise the class into Xml and return it as an Xml document
            XmlDocument   msgXml     = new XmlDocument();
            XmlSerializer serializer = new XmlSerializer(typeof(SoapFaultDetail));

            using (System.IO.MemoryStream writer = new System.IO.MemoryStream())
            {
                serializer.Serialize(writer, msg);
                writer.Flush();
                writer.Position = 0;
                msgXml.Load(writer);
            }
            return(msgXml);
        }
 /// <summary>
 /// Handles instances of <see cref="BusinessProcessException"/>.
 /// </summary>
 /// <param name="bpex">The <see cref="BusinessProcessException"/> exception class.</param>
 /// <param name="msg">The Soap Fault Detail message being created.</param>
 private static void HandleBpException(BusinessProcessException bpex, ref SoapFaultDetail msg)
 {
     // Get the error message and business process error number
     msg.Message         = bpex.Message;
     msg.ExceptionNumber = bpex.Number;
 }
        /// <summary>
        /// Creates a SoapFaultDetail message based upon the type of exception specified.
        /// </summary>
        /// <param name="ex">An exception containing information that is to be added to the SoapFaultDetail message.</param>
        /// <returns>The SoapFaultDetail message.</returns>
        public static XmlDocument CreateSoapFaultDetailMsg(System.Exception ex)
        {
            // Create the message
            SoapFaultDetail msg = new SoapFaultDetail();
            msg.Internal = new SoapFaultDetailInternal();
            msg.Internal.Workflow = new SoapFaultDetailInternalWorkflow();

            // Set the Message, Exception Number and any other specific information
            BusinessProcessException bpex = ex as BusinessProcessException;
            DacSqlException dex = ex as DacSqlException;
            if (bpex != null)
            {
                // A workflow engine business process exception
                HandleBpException(bpex, ref msg);
            }
            else if (dex != null)
            {
                // A workflow engine data access component (DAC) exception
                HandleDacException(dex, ref msg);
            }
            else
            {
                // Handle it as a generic System.Exception
                HandleSystemException(ex, ref msg);
            }

            // Category
            switch (GetExceptionCategory(ex))
            {
                case WorkflowExceptionCategory.Error:
                    msg.Category = SoapFaultDetailCategory.Error;
                    break;
                case WorkflowExceptionCategory.Warning:
                    msg.Category = SoapFaultDetailCategory.Warning;
                    break;
            }

            // Exception Case Number
            msg.ExceptionCaseNumber = Framework.ExceptionManagement.ExceptionCaseNumber.Generate();

            // Exception Code
            msg.ExceptionCode = GetExceptionCode(ex);

            // Internal - Subsystem
            msg.Internal.Subsystem = Framework.Subsystem.WorkflowEngine.ToString();

            // Internal - Source
            msg.Internal.Source = ex.Source;

            // Internal - Stack Trace
            msg.Internal.StackTrace = ex.StackTrace.Trim();

            // Internal - Workflow - Workflow Server
            msg.Internal.Workflow.WorkflowServer = System.Environment.MachineName;

            // Internal - Workflow - Orchestration Name
            // Note: We are trying to get information about the orchestration in which the error occurred.
            //       However, if there is a messaging error (e.g. a message could not be delivered to a
            //       SOAP web service, the error will occur in an assembly in the BizTalk Engine, thus the
            //       top-level stack frame will be the BizTalk Engine and not the orchestration.
            //       Also, if there is an error in a component that is called from an Expression shape, the
            //       top-level stack frame will be the component and not the orchestration.
            //       Variable 'sf' will be null if the exception occurred outside of Orchestration
            StackFrame sf = Framework.ExceptionManagement.ExceptionManager.GetStackFrameByNamespace(ex, ".Orchestrations");
            if (sf == null)
            {
                msg.Internal.Workflow.OrchestrationName = "";
            }
            else
            {
                msg.Internal.Workflow.OrchestrationName = sf.GetMethod().DeclaringType.FullName;
            }

            // Serialise the class into Xml and return it as an Xml document
            XmlDocument msgXml = new XmlDocument();
            XmlSerializer serializer = new XmlSerializer(typeof(SoapFaultDetail));
            using (System.IO.MemoryStream writer = new System.IO.MemoryStream())
            {
                serializer.Serialize(writer, msg);
                writer.Flush();
                writer.Position = 0;
                msgXml.Load(writer);
            }
            return msgXml;
        }
        /// <summary>
        /// Handles instances of <see cref="System.Exception"/>.
        /// </summary>
        /// <param name="ex">The <see cref="System.Exception"/> exception class.</param>
        /// <param name="msg">The Soap Fault Detail message being created.</param>
        private static void HandleSystemException(System.Exception ex, ref SoapFaultDetail msg)
        {
            // Get the error message
            msg.Message = ex.Message;

            // Get the error number
            // .NET Exceptions are type-based, but each type has a unique HResult property, so we'll use this instead.
            msg.ExceptionNumber = Framework.ExceptionManagement.ExceptionManager.GetExHResult(ex);
        }
        /// <summary>
        /// Handles instances of <see cref="DacSqlException"/>.
        /// </summary>
        /// <param name="dex">The <see cref="DacSqlException"/> exception class.</param>
        /// <param name="msg">The Soap Fault Detail message being created.</param>
        private static void HandleDacException(DacSqlException dex, ref SoapFaultDetail msg)
        {
            // Get the error message and business process error number
            msg.Message = dex.DetailedMessage;                              // not the 'Message' property
            msg.ExceptionNumber = dex.Number;

            // Now we need to add the database-specific info
            msg.Internal.Database = new SoapFaultDetailInternalDatabase();
            msg.Internal.Database.DatabaseServer = dex.DatabaseServer;
            msg.Internal.Database.Severity = dex.Severity;
            msg.Internal.Database.Procedure = dex.Procedure;
            msg.Internal.Database.LineNumber = dex.LineNumber;
        }
 /// <summary>
 /// Handles instances of <see cref="BusinessProcessException"/>.
 /// </summary>
 /// <param name="bpex">The <see cref="BusinessProcessException"/> exception class.</param>
 /// <param name="msg">The Soap Fault Detail message being created.</param>
 private static void HandleBpException(BusinessProcessException bpex, ref SoapFaultDetail msg)
 {
     // Get the error message and business process error number
     msg.Message = bpex.Message;
     msg.ExceptionNumber = bpex.Number;
 }