Ejemplo n.º 1
0
 protected void SetupMockObjects()
 {
     Plugin = MockRepository.GenerateMock <T>();
     Plugin.ElevatedOrganizationService = MockRepository.GenerateStub <IOrganizationService>();
     Plugin.OrganizationService         = MockRepository.GenerateStub <IOrganizationService>();
     Plugin.OrganizationServiceFactory  = MockRepository.GenerateStub <IOrganizationServiceFactory>();
     Plugin.TracingService         = MockRepository.GenerateStub <ITracingService>();
     Plugin.PluginExecutionContext = MockRepository.GenerateStub <IPluginExecutionContext>();
     Plugin.ServiceProvider        = MockRepository.GenerateStub <IServiceProvider>();
     ActualException = null;
 }
Ejemplo n.º 2
0
        private static string BuildErrorMessage(Exception exception)
        {
            List <string> result = new List <string>();

            //result.Add("Es ist ein Fehler aufgetreten!");

            if (exception.GetType() == typeof(InvalidPluginExecutionException))
            {
                InvalidPluginExecutionException ex = (InvalidPluginExecutionException)exception;
                result.Add(ex.Message);
            }
            else if (exception.GetType() == typeof(FaultException <OrganizationServiceFault>))
            {
                FaultException <OrganizationServiceFault> ex = (FaultException <OrganizationServiceFault>)exception;
                result.Add(ex.Message);
            }
            else if (exception.GetType() == typeof(TimeoutException))
            {
                TimeoutException ex = (TimeoutException)exception;
                result.Add(string.Format("Message: {0}", ex.Message));
                result.Add(string.Format("Stack Trace: {0}", ex.StackTrace));
                result.Add(string.Format("Inner Fault: {0}",
                                         null == ex.InnerException.Message ? "Has Inner Fault" : "No Inner Fault"));
            }
            else
            {
                Exception ex = exception;
                result.Add(string.Format(ex.Message));

                // Display the details of the inner exception.
                if (ex.InnerException != null)
                {
                    result.Add(string.Format(ex.InnerException.Message));

                    FaultException <Microsoft.Xrm.Sdk.OrganizationServiceFault> fe = ex.InnerException
                                                                                     as FaultException <Microsoft.Xrm.Sdk.OrganizationServiceFault>;
                    if (fe != null)
                    {
                        result.Add(string.Format("Timestamp: {0}", fe.Detail.Timestamp));
                        result.Add(string.Format("Code: {0}", fe.Detail.ErrorCode));
                        result.Add(string.Format("Message: {0}", fe.Detail.Message));
                        result.Add(string.Format("Trace: {0}", fe.Detail.TraceText));
                        result.Add(string.Format("Inner Fault: {0}",
                                                 null == fe.Detail.InnerFault ? "Has Inner Fault" : "No Inner Fault"));
                    } //if
                }     //if
            }         //if

            return(string.Join(Environment.NewLine, result.ToArray()));
        }//BuildErrorMessage
Ejemplo n.º 3
0
 public void Execute(IServiceProvider serviceProvider)
 {
     try
     {
         LocalPluginContext localcontext = new LocalPluginContext(serviceProvider);
         Execute(localcontext);
     }
     catch (Exception e)
     {
         if (e is InvalidPluginExecutionException)
         {
             // Let InvalidPluginExecutionExceptions flow without wrapping them
             throw;
         }
         var ex = new InvalidPluginExecutionException($"An error has occurred in CRM plugin '{GetType().Name}': {e.Message}", e);
         throw ex;
     }
 }
        /// <summary>
        /// Initiate the base plugin context and all member variables.
        /// </summary>
        /// <param name="serviceProvider">The ServiceProvider object passed by the Execute method</param>
        public void Execute(IServiceProvider serviceProvider)
        {
            try
            {
                if (serviceProvider == null)
                {
                    throw new ArgumentNullException("ServiceProvider is null.");
                }

                // Obtain the execution context from the service provider.
                this.context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
                if (this.context == null)
                {
                    throw new Exception("Could not execute plugin:  The plugin context was null");
                }

                this.serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
                if (this.serviceFactory != null)
                {
                    this.service = this.serviceFactory.CreateOrganizationService(this.context.UserId);
                }
                else
                {
                    throw new Exception("Could not execute plugin:  The organization service was null");
                }

                ////Extract the tracing service for use in debugging sandboxed plug-ins.
                this.tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));

                ////call abstract method
                this.Execute();
            }
            catch (Exception e)
            {
                if (e is InvalidPluginExecutionException)
                {
                    //// Let InvalidPluginExecutionExceptions flow without wrapping them
                    throw;
                }

                var ex = new InvalidPluginExecutionException($"An error has occurred in CRM plugin '{GetType().Name}': {e.Message}", e);
                throw ex;
            }
        }
Ejemplo n.º 5
0
        public static BaseData CreateExceptionEventData(BaseData data, InvalidPluginExecutionException ex, IPluginExecutionContext context)
        {
            data.properties = new Dictionary <string, string>();
            data.properties.Add("InitiatingUserId", context.InitiatingUserId.ToString());
            data.properties.Add("RequestId", context.RequestId.ToString());
            data.properties.Add("OperationId", context.OperationId.ToString());
            data.properties.Add("CorrelationId", context.CorrelationId.ToString());
            data.properties.Add("MessageName", context.MessageName);
            data.properties.Add("OrganizationId", context.OrganizationId.ToString());
            data.properties.Add("PrimaryEntityId", context.PrimaryEntityId.ToString());
            data.properties.Add("Stage", context.Stage.ToString());
            data.properties.Add("UserId", context.UserId.ToString());

            data.exceptions = new List <ExceptionDetails>();
            data.exceptions.Add(new ExceptionDetails()
            {
                message  = ex.Message,
                typeName = ex.GetType().ToString(),
                stack    = ex.StackTrace
            });
            return(data);
        }
        protected override void LogContextAndHandleException(Exception exc)
        {
            this.AddTraceDetailsInfo(exc, false, true);

            var traceDetails = this.GetTraceDetails(exc);
            var customVerboseLogSwitchedOn = this.PluginCtx.CustomVerboseLogSwitchedOn;
            var saveLog = true;
            InvalidPluginExecutionException exceptionToThrow;

            var saveTraceDetailsToTraceText           = true;
            var saveParamsImagesSharedVarsToTraceText = true;

            if (exc == null)
            {
                exceptionToThrow = null;
                saveLog          = customVerboseLogSwitchedOn;
            }
            else if (exc is InvalidPluginExecutionException)
            {
                exceptionToThrow = (InvalidPluginExecutionException)exc;
                saveLog          = customVerboseLogSwitchedOn;
            }
            else if (exc is PluginBusinessLogicException)
            {
                exceptionToThrow = new InvalidPluginExecutionException(exc.Message);
                saveLog          = customVerboseLogSwitchedOn;
            }
            else if (exc is PluginBusinessLogicExceptionWithSimpleLogging)
            {
                exceptionToThrow = new InvalidPluginExecutionException(exc.Message);
                saveParamsImagesSharedVarsToTraceText = customVerboseLogSwitchedOn;
                saveTraceDetailsToTraceText           = false;
            }
            else if (exc is PluginBusinessLogicExceptionWithFullLogging)
            {
                exceptionToThrow = new InvalidPluginExecutionException(exc.Message);
            }
            else if (exc is PluginIgnoredExceptionWithLogging)
            {
                exceptionToThrow = null;
            }
            else
            {
                var logId = Guid.NewGuid();
                traceDetails     = $"\r\nSorry, an error occurred.\r\nError ID: {logId}.\r\n\r\n{traceDetails}";
                exceptionToThrow = new InvalidPluginExecutionException(traceDetails);
            }

            if (saveLog)
            {
                var pluginCtx     = this.PluginCtx;
                var pluginExecCtx = pluginCtx.ExecContext;
                this.TracingService.Trace("- CURRENT CONTEXT INFO -");
                this.TracingService.Trace($"PrimaryEntityId: {pluginExecCtx.PrimaryEntityId}");
                this.TracingService.Trace($"PrimaryEntityName: {pluginExecCtx.PrimaryEntityName}");
                this.TracingService.Trace($"Stage: {pluginExecCtx.Stage}");
                this.TracingService.Trace($"Depth: {pluginExecCtx.Depth}");
                this.TracingService.Trace($"UserId: {pluginExecCtx.UserId}");
                this.TracingService.Trace($"InitiatingUserId: {pluginExecCtx.InitiatingUserId}");

                if (saveParamsImagesSharedVarsToTraceText)
                {
                    this.TracingService.Trace(
                        $"\r\nINPUT PARAMETERS\r\n: {SerializeAndPrepareForMemoField(pluginExecCtx.InputParameters)}");
                    this.TracingService.Trace(
                        $"OUTPUT PARAMETERS\r\n: {SerializeAndPrepareForMemoField(pluginExecCtx.OutputParameters)}");
                    this.TracingService.Trace(
                        $"POST IMAGES\r\n: {SerializeAndPrepareForMemoField(pluginExecCtx.PostEntityImages)}");
                    this.TracingService.Trace(
                        $"PRE IMAGES\r\n: {SerializeAndPrepareForMemoField(pluginExecCtx.PreEntityImages)}");
                    this.TracingService.Trace(
                        $"SHARED VARIABLES\r\n: {SerializeAndPrepareForMemoField(pluginExecCtx.SharedVariables)}");
                }

                var parentExecCtx = pluginExecCtx.ParentContext;
                if (parentExecCtx != null)
                {
                    this.TracingService.Trace("\r\n- PARENT CONTEXT INFO -");
                    this.TracingService.Trace($"MessageName: {parentExecCtx.MessageName}");
                    this.TracingService.Trace($"PrimaryEntityName: {parentExecCtx.PrimaryEntityName}");
                    this.TracingService.Trace($"PrimaryEntityId: {parentExecCtx.PrimaryEntityId}");
                    this.TracingService.Trace($"Stage: {parentExecCtx.Stage}");
                    this.TracingService.Trace($"Mode: {parentExecCtx.Mode}");
                    this.TracingService.Trace($"UserId: {parentExecCtx.UserId}");
                    this.TracingService.Trace($"InitiatingUserId: {parentExecCtx.InitiatingUserId}");
                    this.TracingService.Trace($"IsInTransaction: {parentExecCtx.IsInTransaction}");
                    this.TracingService.Trace($"OwningExtension: {parentExecCtx.OwningExtension?.Name}");
                    this.TracingService.Trace(
                        $"Shared Variables\r\n: {SerializeAndPrepareForMemoField(parentExecCtx.SharedVariables)}");

                    var traceGrandParentCtx =
                        parentExecCtx.Stage == (int)Stage.MainOperation && parentExecCtx.ParentContext != null;
                    if (traceGrandParentCtx)
                    {
                        var grandParentCtx = parentExecCtx.ParentContext;
                        this.TracingService.Trace("\r\n- GRAND PARENT CONTEXT INFO -");
                        this.TracingService.Trace($"MessageName: {grandParentCtx.MessageName}");
                        this.TracingService.Trace($"PrimaryEntityName: {grandParentCtx.PrimaryEntityName}");
                        this.TracingService.Trace($"PrimaryEntityId: {grandParentCtx.PrimaryEntityId}");
                        this.TracingService.Trace($"Stage: {grandParentCtx.Stage}");
                        this.TracingService.Trace($"Mode: {grandParentCtx.Mode}");
                        this.TracingService.Trace($"UserId: {grandParentCtx.UserId}");
                        this.TracingService.Trace($"InitiatingUserId: {grandParentCtx.InitiatingUserId}");
                        this.TracingService.Trace($"IsInTransaction: {grandParentCtx.IsInTransaction}");
                        this.TracingService.Trace($"OwningExtension: {grandParentCtx.OwningExtension?.Name}");
                        this.TracingService.Trace(
                            $"Shared Variables\r\n: {SerializeAndPrepareForMemoField(grandParentCtx.SharedVariables)}");
                    }
                }

                if (saveTraceDetailsToTraceText)
                {
                    this.TracingService.Trace("\r\n- TRACE DETAILS -");
                    this.TracingService.Trace(traceDetails);
                }
            }

            if (exceptionToThrow != null)
            {
                throw exceptionToThrow;
            }
        }
Ejemplo n.º 7
0
        protected override void LogContextAndHandleException(Exception exc)
        {
            this.AddTraceDetailsInfo(exc);
            var traceDetails               = this.GetTraceDetails(exc);
            var includeTraceText           = true;
            var customVerboseLogSwitchedOn = this.PluginCtx.CustomVerboseLogSwitchedOn;
            var saveLog = true;
            InvalidPluginExecutionException exceptionToThrow;

            if (exc == null)
            {
                exceptionToThrow = null;
                saveLog          = customVerboseLogSwitchedOn;
            }
            else if (exc is InvalidPluginExecutionException)
            {
                exceptionToThrow = (InvalidPluginExecutionException)exc;
                saveLog          = customVerboseLogSwitchedOn;
            }
            else if (exc is PluginBusinessLogicException)
            {
                exceptionToThrow = new InvalidPluginExecutionException(exc.Message);
                saveLog          = customVerboseLogSwitchedOn;
            }
            else if (exc is PluginBusinessLogicExceptionWithSimpleLogging)
            {
                exceptionToThrow = new InvalidPluginExecutionException(exc.Message);
                includeTraceText = false;
            }
            else if (exc is PluginBusinessLogicExceptionWithFullLogging)
            {
                exceptionToThrow = new InvalidPluginExecutionException(exc.Message);
            }
            else if (exc is PluginIgnoredExceptionWithLogging)
            {
                exceptionToThrow = null;
            }
            else
            {
                var logId = Guid.NewGuid();
                traceDetails     = $"\r\nSorry, an error occurred.\r\nError ID: {logId}.\r\n\r\n{traceDetails}";
                exceptionToThrow = new InvalidPluginExecutionException(traceDetails);
            }

            if (saveLog)
            {
                var pluginCtx = this.PluginCtx;
                includeTraceText = includeTraceText || customVerboseLogSwitchedOn;
                const string CustomTraceTextParamName = "CustomTraceTextParam";
                if (includeTraceText)
                {
                    var traceText = this.CustomTracingService.GetTraceInfo(takeCached: true);
                    pluginCtx.SetOutputParameter(CustomTraceTextParamName, traceText);
                }

                const string CustomTraceDetailsParamName = "CustomTraceDetailsParam";
                if (exceptionToThrow != null)
                {
                    pluginCtx.SetOutputParameter(CustomTraceDetailsParamName, traceDetails);
                }

                pluginCtx.NotifyServiceBusEndpoint(this.traceServiceBusEndpointId);

                // ReSharper disable once ConditionIsAlwaysTrueOrFalse
                var removeCustomTraceTextParamFromContext = exceptionToThrow == null && includeTraceText;
                if (removeCustomTraceTextParamFromContext)
                {
                    pluginCtx.ExecContext.OutputParameters.Remove(CustomTraceTextParamName);
                }
            }

            if (exceptionToThrow != null)
            {
                throw exceptionToThrow;
            }
        }
Ejemplo n.º 8
0
        protected override void LogContextAndHandleException(Exception exc)
        {
            this.AddTraceDetailsInfo(exc);
            var traceDetails               = this.GetTraceDetails(exc);
            var includeTraceText           = true;
            var customVerboseLogSwitchedOn = this.PluginCtx.CustomVerboseLogSwitchedOn;
            var error   = exc != null;
            var saveLog = true;
            InvalidPluginExecutionException exceptionToThrow;
            Guid?logId = null;

            if (exc == null)
            {
                exceptionToThrow = null;
                saveLog          = customVerboseLogSwitchedOn;
            }
            else if (exc is InvalidPluginExecutionException)
            {
                exceptionToThrow = (InvalidPluginExecutionException)exc;
                saveLog          = customVerboseLogSwitchedOn;
            }
            else if (exc is PluginBusinessLogicException)
            {
                exceptionToThrow = new InvalidPluginExecutionException(exc.Message);
                saveLog          = customVerboseLogSwitchedOn;
            }
            else if (exc is PluginBusinessLogicExceptionWithSimpleLogging)
            {
                exceptionToThrow = new InvalidPluginExecutionException(exc.Message);
                includeTraceText = customVerboseLogSwitchedOn;
            }
            else if (exc is PluginBusinessLogicExceptionWithFullLogging)
            {
                exceptionToThrow = new InvalidPluginExecutionException(exc.Message);
            }
            else if (exc is PluginIgnoredExceptionWithLogging)
            {
                exceptionToThrow = null;
            }
            else
            {
                logId            = Guid.NewGuid();
                traceDetails     = $"\r\nSorry, an error occurred.\r\nError ID: {logId}.\r\n\r\n{traceDetails}";
                exceptionToThrow = new InvalidPluginExecutionException(traceDetails);
            }

            if (saveLog)
            {
                var    pluginCtx     = this.PluginCtx;
                var    pluginExecCtx = pluginCtx.ExecContext;
                var    logs          = new List <Entity>();
                string traceText     = null;
                if (includeTraceText)
                {
                    traceText = this.CustomTracingService.GetTraceInfo(takeCached: true);
                }

                var includeParentContextInfo = includeTraceText;
                if (includeParentContextInfo)
                {
                    BuildAdvancedPluginExecContextLog(pluginExecCtx.ParentContext, logs);
                }

                // ReSharper disable RedundantArgumentName
                var currentCtxLog =
                    ConvertToAdvancedPluginTrace(pluginExecCtx, saveParamsImagesSharedVars: includeTraceText, logId: logId);
                // ReSharper restore RedundantArgumentName
                var parentCtxLogRef = logs.LastOrDefault()?.ToEntityReference();
                currentCtxLog["pavelkh_traceid"]          = GuidToString(currentCtxLog.Id);
                currentCtxLog["pavelkh_parentcontextref"] = parentCtxLogRef;
                currentCtxLog["pavelkh_subject"]          =
                    $"Plugin {(error ? "Error" : "Trace")} on {pluginCtx.OrganizationName} ({pluginCtx.OrganizationId})";
                currentCtxLog["pavelkh_tracedetails"] = traceDetails;
                currentCtxLog["pavelkh_tracetext"]    = traceText;

                logs.Add(currentCtxLog);

                this.SaveLogs(logs);
            }

            if (exceptionToThrow != null)
            {
                throw exceptionToThrow;
            }
        }
 /// <summary>
 /// Internals the handle.
 /// </summary>
 /// <param name="ex">The executable.</param>
 /// <returns></returns>
 private ErrorAction InternalHandle(InvalidPluginExecutionException ex)
 {
     return new ErrorAction(ConvertToErrorActionType(ex.Status), ex.ErrorCode);
 }
Ejemplo n.º 10
0
        /// <summary>
        /// Executes the WorkFlow.
        /// </summary>
        /// <param name="crmWorkflowContext">The <see cref="LocalWorkflowContext"/> which contains the
        /// <param name="executionContext" > <see cref="CodeActivityContext"/>
        /// </param>
        /// <remarks>
        /// For improved performance, Microsoft Dynamics 365 caches WorkFlow instances.
        /// The WorkFlow's Execute method should be written to be stateless as the constructor
        /// is not called for every invocation of the WorkFlow. Also, multiple system threads
        /// could execute the WorkFlow at the same time. All per invocation state information
        /// is stored in the context. This means that you should not use global variables in WorkFlows.
        /// </remarks>
        public override void ExecuteCRMWorkFlowActivity(CodeActivityContext executionContext, LocalWorkflowContext crmWorkflowContext)
        {
            if (crmWorkflowContext == null)
            {
                throw new ArgumentNullException("crmWorkflowContext");
            }

            //try
            //{
            var tracingService = executionContext.GetExtension <ITracingService>();
            var serviceFactory = executionContext.GetExtension <IOrganizationServiceFactory>();
            var service        = crmWorkflowContext.OrganizationService;
            var adminService   = serviceFactory.CreateOrganizationService(null);

            var postcode = this.Postcode.Get(executionContext);

            tracingService.Trace(string.Format("In GetAddressesForPostcode with PostCode = {0}", postcode));

            // Read the settings
            var url = string.Empty;

            try
            {
                var configSettings = adminService.GetConfigurationStringValues("OSPlaces.AddressbaseFacadeUrl");

                url = configSettings["OSPlaces.AddressbaseFacadeUrl"];
                // url will be something like http://addressfacade.cloudapp.net/address-service/v1/addresses/postcode?key=client1&postcode={0}
                // so we need to substitute the postcode
                url = string.Format(configSettings["OSPlaces.AddressbaseFacadeUrl"], postcode);
            }
            catch (Exception exc)
            {
                throw new InvalidPluginExecutionException("The Address base facade url needs to be configured.");
            }

            var addresses = string.Empty;

            tracingService.Trace(url);

            using (var httpclient = new HttpClient())
            {
                // Synchronous call to address base facade
                var response = httpclient.GetAsync(url).Result;
                response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
                if (!response.IsSuccessStatusCode)
                {
                    if (response.StatusCode != HttpStatusCode.BadRequest)
                    {
                        // Throw exception if its not 400
                        response.EnsureSuccessStatusCode();
                    }
                    else
                    {
                        // Handle error in body that was returned by address base facade
                        // and throw a new one with the error message in it so can be used
                        // in web resource.

                        var httpErrorObject = response.Content.ReadAsStringAsync().Result;
                        tracingService.Trace(string.Format("Facacde Error: {0}", httpErrorObject));

                        // Template for anonymous deserialisation
                        var anonymousErrorObject = new
                        {
                            facade_status_code   = 400,
                            facade_error_message = string.Empty,
                            facade_error_code    = string.Empty,
                            supplier_was_called  = true,
                            supplier_status_code = 400,
                            supplier_response    = new { error = new { statuscode = 400, message = string.Empty } }
                        };
                        var deserializedErrorObject = JsonConvert.DeserializeAnonymousType(httpErrorObject, anonymousErrorObject);

                        var ex = new InvalidPluginExecutionException(deserializedErrorObject.supplier_response.error.message);
                        tracingService.Trace(string.Format("Throwing exception for Facacde Error: {0}", deserializedErrorObject.supplier_response.error.message));
                        throw ex;
                    }
                }
                else
                {
                    addresses = response.Content.ReadAsStringAsync().Result;
                }
            }
            this.Addresses.Set(executionContext, addresses);
            tracingService.Trace(string.Format("Returned addresses: {0}", addresses));
            //}
            //catch (FaultException<OrganizationServiceFault> e)
            //{
            //    throw e;
            //}
        }
        public static InvalidPluginExecutionException BuildInvalidPluginExecutionException(Exception e, Type type, ITracingService tracingService)
        {
            if (tracingService != null)
            {
                tracingService.Trace(e.Message);
                tracingService.Trace(e.StackTrace);
            }

            var additionalInfo = new StringBuilder();

            var executionException = e as InvalidPluginExecutionException;

            if (executionException != null)
            {
                var exc = executionException;
                return(exc);
            }

            var exception = e as FaultException <OrganizationServiceFault>;

            if (exception != null)
            {
                var exc = exception;
                additionalInfo.AppendFormat("\nTimestamp: {0}", exc.Detail.Timestamp);
                additionalInfo.AppendFormat("\nCode: {0}", exc.Detail.ErrorCode);
                additionalInfo.AppendFormat("\nMessage: {0}", exc.Detail.Message);
                additionalInfo.AppendFormat("\nTrace: {0}", exc.Detail.TraceText);
                if (exc.Detail.InnerFault != null)
                {
                    additionalInfo.AppendFormat("\nInner Fault Message: {0}", exc.Detail.InnerFault.Message);
                    additionalInfo.AppendFormat("\nInner Fault Trace: {0}", exc.Detail.InnerFault.TraceText);
                }
            }
            else
            {
                var timeoutException = e as TimeoutException;
                if (timeoutException != null)
                {
                    var exc = timeoutException;
                    additionalInfo.AppendFormat("\nMessage: {0}", exc.Message);
                    additionalInfo.AppendFormat("\nTrace: {0}", exc.StackTrace);
                    if (exc.InnerException != null)
                    {
                        additionalInfo.AppendFormat("\nInner Exception Message: {0}", exc.InnerException.Message);
                        additionalInfo.AppendFormat("\nInner Exception Trace: {0}", exc.InnerException.StackTrace);
                    }
                }
                else
                {
                    additionalInfo.AppendFormat("\nMessage: {0}", e.Message);
                    additionalInfo.AppendFormat("\nTrace: {0}", e.StackTrace);
                    if (e.InnerException != null)
                    {
                        additionalInfo.AppendFormat("\nInner Exception Message: {0}", e.InnerException.Message);
                        additionalInfo.AppendFormat("\nInner Exception Trace: {0}", e.InnerException.StackTrace);
                        var exc = e.InnerException as FaultException <OrganizationServiceFault>;
                        if (exc != null)
                        {
                            additionalInfo.AppendFormat("\nTimestamp: {0}", exc.Detail.Timestamp);
                            additionalInfo.AppendFormat("\nCode: {0}", exc.Detail.ErrorCode);
                            additionalInfo.AppendFormat("\nMessage: {0}", exc.Detail.Message);
                            additionalInfo.AppendFormat("\nTrace: {0}", exc.Detail.TraceText);
                        }
                    }
                }
            }

            const string MessageFormatString =
                "An error occurred in the {0} plug-in. Exception: {1} Details: {2}";

            var message = string.Format(MessageFormatString, type, e.Message, additionalInfo);

            tracingService?.Trace(message);

            var result = new InvalidPluginExecutionException(message, e);

            return(result);
        }