2分钟插件超时未处理异常

时间:2019-07-17 01:24:09

标签: dynamics-crm dynamics-crm-online dynamics-365

我正在尝试通过使用Thread.Sleep(120000)生成超时来模拟插件上的2分钟超时,但是当出现异常时,我的try catch似乎无法捕获它们,即使是finally块被跳过。

我将如何正确捕获它,以便针对此错误创建案例记录?

我尝试使用不同的catch异常无济于事。我什至尝试对插件进行性能分析,但由于错误,它也不会分析插件。

protected override void ExecuteCrmPlugin(LocalPluginContext localContext) {

        IPluginExecutionContext context = localContext.PluginExecutionContext;
        IOrganizationService service = localContext.OrganizationService;
        ITracingService tracer = localContext.TracingService;

        try {
            if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity) {

                Entity entity = (Entity)context.InputParameters["Target"];

                if (context.MessageName.ToLower() != "create")
                    return;

                if (entity.LogicalName.ToLower() == Contact.EntityLogicalName) {
                    tracer.Trace("Sleep for 2 min");
                    Thread.Sleep(120000);
                }
            }
        }

        catch (System.ServiceModel.FaultException<System.TimeoutException ex) {
            throw new InvalidPluginExecutionException("An error occurred in the plug-in.", ex);
        }
        catch (System.ServiceModel.FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault ex) {
            throw new InvalidPluginExecutionException("An error occurred in the plug-in.", ex);
        }
        catch (TimeoutException e) {
            throw new InvalidPluginExecutionException("A timeout has occurred during the execution of the plugin.", e);
        }
        catch (FaultException ex) {
            throw new InvalidPluginExecutionException("Err occurred.", ex);
        }
        catch (Exception ex) {
            tracer.Trace(ex.ToString());
            throw;
        }
        finally {
            tracer.Trace("Finally");
        }
    }

在基类中,我也有相同的捕获块。

错误是:

Unhandled exception: 
Exception type: System.ServiceModel.FaultException`1[Microsoft.Xrm.Sdk.OrganizationServiceFault]
Message: An unexpected error occurred from ISV code. (ErrorType = ClientError) Unexpected exception from plug-in (Execute):  MyPlugin.Plugins.PreCreateContact: System.TimeoutException: Couldn’t complete execution of the MyPlugin.Plugins.PreCreateContact plug-in within the 2-minute limit.Detail:

<OrganizationServiceFault xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/xrm/2011/Contracts">
  <ActivityId>397e0f4c-2e16-43ea-9368-ea76607820a5</ActivityId>
  <ErrorCode>-2147220956</ErrorCode>
  <ErrorDetails xmlns:d2p1="http://schemas.datacontract.org/2004/07/System.Collections.Generic" />
  <HelpLink i:nil="true" />
  <Message>An unexpected error occurred from ISV code. (ErrorType = ClientError) Unexpected exception from plug-in (Execute):  MyPlugin.Plugins.PreCreateContact: System.TimeoutException: Couldn’t complete execution of the MyPlugin.Plugins.PreCreateContact plug-in within the 2-minute limit.</Message>
  <Timestamp>2019-07-17T00:49:48.360749Z</Timestamp>
  <ExceptionRetriable>false</ExceptionRetriable>
  <ExceptionSource>PluginExecution</ExceptionSource>
  <InnerFault i:nil="true" />
  <OriginalException>System.TimeoutException: Couldn’t complete execution of the MyPlugin.Plugins.PreCreateContact plug-in within the 2-minute limit.
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Microsoft.Crm.Sandbox.SandboxAppDomainHelper.Execute(IOrganizationServiceFactory organizationServiceFactory, Dictionary`2 sandboxServices, String pluginTypeName, String pluginConfiguration, String pluginSecureConfig, IPluginExecutionContext requestContext, Boolean enablePluginStackTrace, Boolean chaosFailAppDomain, String crashOnPluginExceptionMessage)
   at Microsoft.Crm.Sandbox.SandboxAppDomainHelper.Execute(IOrganizationServiceFactory organizationServiceFactory, Dictionary`2 sandboxServices, String pluginTypeName, String pluginConfiguration, String pluginSecureConfig, IPluginExecutionContext requestContext, Boolean enablePluginStackTrace, Boolean chaosFailAppDomain, String crashOnPluginExceptionMessage)
   at Microsoft.Crm.Sandbox.SandboxWorker.&lt;&gt;c__DisplayClass3_0.&lt;Execute&gt;b__0()</OriginalException>
  <TraceText>
Entered MyPlugin.Plugins.PreCreateContact.Execute(), Correlation Id: 0c2b0dd3-d27c-46ea-a7e2-90c0729b326e, Initiating User: 61e01dfa-668a-e811-8107-123456
</TraceText>
</OrganizationServiceFault>

1 个答案:

答案 0 :(得分:0)

我猜一旦插件达到2分钟超时,我们处理任何东西的能力就结束了。这很有意义-如果系统允许我们在2分钟的超时后运行catch块,则catch块可能会再运行一分钟或五分钟。

我采用的一种允许插件或自定义工作流程处理可能会花费超过2分钟超时的方法的方法是使用cancellation token来在超时之前正常关闭。您可以在115秒内抛出自己的异常并优雅地取消,而不必捕获平台的超时异常。

我什至可以将执行状态保存为XML并保存在注释中,然后将插件重新触发到7次无限循环限制。除此之外,我还创建了四个流程,每个流程每小时重复一次,错开15分钟-即在主流程之后的15、30、45和60分钟。 (一个进程可以每小时重复一次,而不会触发无限循环异常)。这些过程捕获了在运行7次后仍保持其状态的所有作业,然后将其重新触发了另外7次。使用这种方法,我的工作流程完成了计算,而整个过程耗时数小时。

请记住,这可能是滥用了异步处理系统。我承认这很麻烦,但是用例需要完全在Dynamics内部处理大型计算。当然,“逃避”沙箱超时的标准方法是将处理移至外部服务(例如Azure API,Azure Functions,Flow,Logic Apps等)