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; }
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
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; } }
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; } }
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; } }
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); }
/// <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); }