Поделиться через


Устранение неполадок подключаемых модулей Dataverse

В этой статье содержатся сведения об ошибках, которые могут возникать во время выполнения подключаемых модулей или ошибок Dataverse, связанных с подключаемыми модулями, и о том, как избежать или исправить их.

Ошибка "Не удалось завершить преобразование времени"

Код ошибки: -2147220956
Сообщение об ошибке: преобразование не удалось завершить, так как предоставленный DataTime не имеет правильного набора свойств Kind. Например, если свойство Kind имеет значение DateTimeKind.Local, исходный часовой пояс должен быть TimeZoneInfo.Local.

Эта ошибка может возникать во время TimeZoneInfo.ConvertTimeToUtc(DateTime, TimeZoneInfo) вызова в коде подключаемого модуля, чтобы преобразовать DateTime значение в часовом поясе Сантьяго или Веду в координированное универсальное время (UTC).

Эта ошибка вызвана известным ограничением продукта и в настоящее время не существует обходного решения.

Дополнительные сведения см. в разделе "Указание параметров часового пояса" для пользователя.

Ошибка "Сбой рабочего процесса песочницы"

Код ошибки: -2147204723
Сообщение об ошибке: сбой выполнения подключаемого модуля, так как рабочий процесс песочницы завершился сбоем. Обычно это связано с ошибкой в коде подключаемого модуля.

Эта ошибка просто означает, что рабочий процесс, выполняющий код подключаемого модуля, произошел сбой. Подключаемый модуль может быть причиной сбоя, но он также может быть еще одним подключаемым модулем, работающим одновременно для вашей организации. Так как процесс произошел сбой, мы не можем извлечь более конкретную информацию о том, почему он произошел сбой. Но после изучения данных из аварийных дампов после того, мы обнаружили, что эта ошибка обычно возникает из-за одной из четырех причин:

Необработанное исключение в подключаемом модуле

При написании подключаемого модуля следует попытаться предвидеть, какие операции могут завершиться ошибкой и упаковать их в блок try-catch. При возникновении ошибки следует использовать InvalidPluginExecutionException класс для корректного завершения операции с ошибкой, понятной для пользователя.

Дополнительные сведения см. в разделе "Обработка исключений в подключаемых модулях".

Типичным сценарием этого исключения является использование метода HttpClient.SendAsync или HttpClient.GetAsync. Эти методы HttpClient являются асинхронными операциями, возвращающими задачу. Чтобы работать в подключаемом модуле, где код должен быть синхронным, пользователи могут использовать TResult> задачи<. Свойство result. При возникновении Result ошибки возвращается АгрегатException. Объединение AggregateException нескольких сбоев в одно исключение, которое может быть трудно обрабатывать. Лучше всего использовать task<TResult>. GetAwaiter().GetResult() из-за распространения результатов в виде конкретной ошибки, вызвавшей сбой.

В следующем примере показан правильный способ управления исключением и исходящим вызовом с помощью метода HttpClient.GetAsync . Этот подключаемый модуль пытается получить текст ответа для набора URI в небезопасной конфигурации для шага, зарегистрированного для него.

using Microsoft.Xrm.Sdk;
using System;
using System.Net.Http;

namespace ErrorRepro
{
    public class AsyncError : IPlugin
    {
        private readonly string webAddress;

        public AsyncError(string unsecureConfig)
        {
            if (string.IsNullOrEmpty(unsecureConfig)) {
                throw new InvalidPluginExecutionException("The ErrorRepro.AsyncError plug-in requires that a Url be set in the unsecure configuration for the step registration.");
            }
            webAddress = unsecureConfig;

        }

        public void Execute(IServiceProvider serviceProvider)
        {
            ITracingService tracingService =
            (ITracingService)serviceProvider.GetService(typeof(ITracingService));

            tracingService.Trace($"Starting ErrorRepro.AsyncError");
            tracingService.Trace($"Sending web request to {webAddress}");

            try
            {
                string responseText = GetWebResponse(webAddress, tracingService);
                tracingService.Trace($"Result: {responseText.Substring(0, 100)}");
            }
            catch (Exception ex)
            {
                tracingService.Trace($"Error: ErrorRepro.AsyncError {ex.Message}");
                throw new InvalidPluginExecutionException(ex.Message);
            }
            tracingService.Trace($"Ending ErrorRepro.AsyncError");
        }

        //Gets the text response of an outbound web service call
        public string GetWebResponse(string webAddress, ITracingService tracingService)
        {
            try
            {
                using (HttpClient client = new HttpClient())
                {
                    client.Timeout = TimeSpan.FromMilliseconds(15000); //15 seconds
                    client.DefaultRequestHeaders.ConnectionClose = true; //Set KeepAlive to false

                    HttpResponseMessage response = client.GetAsync(webAddress).GetAwaiter().GetResult(); //Make sure it is synchronous
                    response.EnsureSuccessStatusCode();

                    tracingService.Trace($"ErrorRepro.AsyncError.GetWebResponse succeeded.");

                    string responseContent = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); //Make sure it is synchronous

                    tracingService.Trace($"ErrorRepro.AsyncError.GetWebResponse responseContent parsed successfully.");

                    return responseContent;

                }
            }
            catch (Exception ex)
            {
                //Capture the inner exception message if it exists.
                // It should have a more specific detail.
                string innerExceptionMessage = string.Empty;
                if (ex.InnerException != null) {
                    innerExceptionMessage = ex.InnerException.Message;
                }

                tracingService.Trace($"Error in ErrorRepro.AsyncError : {ex.Message} InnerException: {innerExceptionMessage}");
                if (!string.IsNullOrEmpty(innerExceptionMessage))
                {
                    throw new Exception($"A call to an external web service failed. {innerExceptionMessage}", ex);
                }

                throw new Exception("A call to an external web service failed.", ex);
            }
        }
    }
}

Использование потоков для очереди без попытки и перехвата в делегате потока

Не следует использовать шаблоны параллельного выполнения в подключаемых модулях. Этот анти-шаблон вызван в статье о рекомендациях. Не используйте параллельное выполнение в подключаемых модулях и действиях рабочего процесса. С помощью этих шаблонов могут возникнуть проблемы, связанные с управлением транзакцией в синхронном подключаемом модуле. Однако еще одна причина не использовать эти шаблоны заключается в том, что любая работа, выполняемая за пределами блока делегата try/catch потока, может завершить рабочий процесс.

Внимание

Когда рабочий процесс завершает работу, выполнение подключаемого модуля и других подключаемых модулей, работающих в данный момент в этом процессе, завершится. Это включает подключаемые модули, которые вы не владеете или поддерживаете.

Application Insights для спасения

В прошлом получение трассировки стека или другой информации о выполнении для необработанных исключений подключаемого модуля из аварийного рабочего процесса было невозможно. Однако Dataverse теперь обеспечивает поддержку сбоев выполнения журнала в Application Insights. Чтобы включить эту функцию, можно связать Application Insights с средой, в которой зарегистрирован подключаемый модуль. После связывания ведение журнала сбоев подключаемого модуля происходит автоматически.

Дополнительные сведения см. в статье "Экспорт данных в Application Insights".

После связывания среды Application Insights следующие данные о сбое рабочего процесса будут доступны для устранения проблемы.

Пример отчета о аварийном сбое подключаемого модуля Application Insights.

Чтобы перейти к отчету о сбоях в Application Insights, выполните следующие действия.

  1. Связывание Application Insights с вашей средой.
  2. Подождите, пока исключение подключаемого модуля приведет к ошибке сбоя рабочего процесса.
  3. В Центре администрирования Power Platform перейдите в Application Insights.
  4. На странице Application Insights выберите "Сбои " на левой панели.
  5. На странице "Сбои" выберите "Исключения".
  6. В разделе "Идентификатор проблемы исключения" в списке "Общий " выберите Microsoft.PowerPlatform.Dataverse.PluginWorkerCrashException.
  7. В правой части страницы в разделе "Общее" выберите PluginWorkerCrashException. Теперь вы увидите сведения обо всех записанных исключениях сбоя рабочего процесса.
  8. Найдите и выберите требуемое исключение на левой панели, и отчет об исключении будет отображаться справа от страницы (см. предыдущий снимок экрана. Пример).
  9. Чтобы получить доступ к трассировке стека, разверните crashDetails в отчете.

Ошибка переполнения стека в подключаемом модуле

Этот тип ошибки чаще всего возникает сразу после внесения некоторых изменений в код подключаемого модуля. Некоторые пользователи используют собственный набор базовых классов, чтобы упростить свой опыт разработки. Иногда эти ошибки возникают из изменений в этих базовых классах, от которых зависит конкретный подключаемый модуль.

Например, рекурсивный вызов без условия завершения или условия завершения, которое не охватывает все сценарии, может привести к возникновению этой ошибки. Дополнительные сведения см. в разделе "Примечания класса > StackOverflowException".

Необходимо просмотреть все изменения кода, которые были применены недавно для подключаемого модуля, и любой другой код, от который зависит подключаемый модуль.

Пример

Следующий код подключаемого модуля приводит StackOverflowException к возникновению рекурсивного вызова без ограничений. Несмотря на использование трассировки и попытки захвата ошибки, трассировка и ошибка не возвращаются, так как рабочий процесс, который будет обрабатывать их завершен.

using Microsoft.Xrm.Sdk;
using System;

namespace ErrorRepro
{
    public class SOError : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {
            ITracingService tracingService =
           (ITracingService)serviceProvider.GetService(typeof(ITracingService));

            tracingService.Trace($"Starting ErrorRepro.SOError");

            try
            {
                tracingService.Trace($"Calling RecursiveMethodWithNoLimit to trigger StackOverflow error.");

                RecursiveMethodWithNoLimit(tracingService); //StackOverflowException occurs here.
            }
            catch (Exception ex)
            {
                //This trace will not be written
                tracingService.Trace($"Error in ErrorRepro.SOError {ex.Message}");

                //This error will never be thrown
                throw new InvalidPluginExecutionException($"Error in ErrorRepro.SOError. {ex.Message}");
            }

            //This trace will never be written
            tracingService.Trace($"Ending ErrorRepro.SOError");
        }

        public static void RecursiveMethodWithNoLimit(ITracingService tracingService)
        {
            tracingService.Trace($"Starting ErrorRepro.SOError.RecursiveMethodWithNoLimit");

            RecursiveMethodWithNoLimit(tracingService);

            tracingService.Trace($"Ending ErrorRepro.SOError.RecursiveMethodWithNoLimit");
        }
    }
}

На шаге синхронного подключаемого модуля код подключаемого модуля, который ранее отображалось, возвращает следующую ошибку в веб-API, когда запрос настроен на включение дополнительных сведений с ошибками.

{
    "error": {
        "code": "0x8004418d",
        "message": "The plug-in execution failed because the Sandbox Worker process crashed. This is typically due to an error in the plug-in code.\r\nSystem.ServiceModel.CommunicationException: The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error.\r\n   at Microsoft.Crm.Sandbox.SandboxWorkerProcess.Execute(SandboxCallInfo callInfo, SandboxPluginExecutionContext requestContext, Guid pluginAssemblyId, Int32 sourceHash, String assemblyName, Guid pluginTypeId, String pluginTypeName, String pluginConfiguration, String pluginSecureConfig, Boolean returnTraceInfo, Int64& wcfExecInMs, Int64& initializeInMs, Int64& trackCallInMs, Int64& trackGoodReturnInMs, Int64& waitInMs, Int64& taskStartDelay) +0x330: Microsoft Dynamics CRM has experienced an error. Reference number for administrators or support: #8503641A",
        "@Microsoft.PowerApps.CDS.ErrorDetails.ApiExceptionSourceKey": "Plugin/ErrorRepro.SOError, ErrorRepro, Version=1.0.0.0, Culture=neutral, PublicKeyToken=c2bee3e550ec0851",
        "@Microsoft.PowerApps.CDS.ErrorDetails.ApiStepKey": "d5958631-b87e-eb11-a812-000d3a4f50a7",
        "@Microsoft.PowerApps.CDS.ErrorDetails.ApiDepthKey": "1",
        "@Microsoft.PowerApps.CDS.ErrorDetails.ApiActivityIdKey": "a3028bda-73c2-4eef-bcb5-157c5a4c323e",
        "@Microsoft.PowerApps.CDS.ErrorDetails.ApiPluginSolutionNameKey": "Active",
        "@Microsoft.PowerApps.CDS.ErrorDetails.ApiStepSolutionNameKey": "Active",
        "@Microsoft.PowerApps.CDS.ErrorDetails.ApiExceptionCategory": "SystemFailure",
        "@Microsoft.PowerApps.CDS.ErrorDetails.ApiExceptionMesageName": "SandboxWorkerNotAvailable",
        "@Microsoft.PowerApps.CDS.ErrorDetails.ApiExceptionHttpStatusCode": "500",
        "@Microsoft.PowerApps.CDS.HelpLink": "http://go.microsoft.com/fwlink/?LinkID=398563&error=Microsoft.Crm.CrmException%3a8004418d&client=platform",
        "@Microsoft.PowerApps.CDS.TraceText": "\r\n[ErrorRepro: ErrorRepro.SOError]\r\n[d5958631-b87e-eb11-a812-000d3a4f50a7: ErrorRepro.SOError: Create of account]\r\n\r\n",
        "@Microsoft.PowerApps.CDS.InnerError.Message": "The plug-in execution failed because the Sandbox Worker process crashed. This is typically due to an error in the plug-in code.\r\nSystem.ServiceModel.CommunicationException: The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error.\r\n   at Microsoft.Crm.Sandbox.SandboxWorkerProcess.Execute(SandboxCallInfo callInfo, SandboxPluginExecutionContext requestContext, Guid pluginAssemblyId, Int32 sourceHash, String assemblyName, Guid pluginTypeId, String pluginTypeName, String pluginConfiguration, String pluginSecureConfig, Boolean returnTraceInfo, Int64& wcfExecInMs, Int64& initializeInMs, Int64& trackCallInMs, Int64& trackGoodReturnInMs, Int64& waitInMs, Int64& taskStartDelay) +0x330: Microsoft Dynamics CRM has experienced an error. Reference number for administrators or support: #8503641A"
    }
}

Ниже показано, как эта ошибка записывается в подключаемый журнал трассировки:

Unhandled exception: 
Exception type: System.ServiceModel.FaultException`1[Microsoft.Xrm.Sdk.OrganizationServiceFault]
Message: The plug-in execution failed because the Sandbox Worker process crashed. This is typically due to an error in the plug-in code.
System.ServiceModel.CommunicationException: The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error.
   at Microsoft.Crm.Sandbox.SandboxWorkerProcess.Execute(SandboxCallInfo callInfo, SandboxPluginExecutionContext requestContext, Guid pluginAssemblyId, Int32 sourceHash, String assemblyName, Guid pluginTypeId, String pluginTypeName, String pluginConfiguration, String pluginSecureConfig, Boolean returnTraceInfo, Int64& wcfExecInMs, Int64& initializeInMs, Int64& trackCallInMs, Int64& trackGoodReturnInMs, Int64& waitInMs, Int64& taskStartDelay) +0x330: Microsoft Dynamics CRM has experienced an error. Reference number for administrators or support: #4BC22433Detail: 
<OrganizationServiceFault xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/xrm/2011/Contracts">
  <ActivityId>48c5818e-4912-42f0-b1b6-e3bbe7ae013d</ActivityId>
  <ErrorCode>-2147204723</ErrorCode>
  <ErrorDetails xmlns:d2p1="http://schemas.datacontract.org/2004/07/System.Collections.Generic" />
  <HelpLink i:nil="true" />
  <Message>The plug-in execution failed because the Sandbox Worker process crashed. This is typically due to an error in the plug-in code.
System.ServiceModel.CommunicationException: The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error.
   at Microsoft.Crm.Sandbox.SandboxWorkerProcess.Execute(SandboxCallInfo callInfo, SandboxPluginExecutionContext requestContext, Guid pluginAssemblyId, Int32 sourceHash, String assemblyName, Guid pluginTypeId, String pluginTypeName, String pluginConfiguration, String pluginSecureConfig, Boolean returnTraceInfo, Int64&amp; wcfExecInMs, Int64&amp; initializeInMs, Int64&amp; trackCallInMs, Int64&amp; trackGoodReturnInMs, Int64&amp; waitInMs, Int64&amp; taskStartDelay) +0x330: Microsoft Dynamics CRM has experienced an error. Reference number for administrators or support: #4BC22433</Message>
  <Timestamp>2021-03-06T22:14:22.0629638Z</Timestamp>
  <ExceptionRetriable>false</ExceptionRetriable>
  <ExceptionSource>WorkerCommunication</ExceptionSource>
  <InnerFault i:nil="true" />
  <OriginalException>System.ServiceModel.CommunicationException: The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error.

Server stack trace: 
   at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
   at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

Exception rethrown at [0]: 
   at Microsoft.Crm.Sandbox.SandboxWorkerProcess.Execute(SandboxCallInfo callInfo, SandboxPluginExecutionContext requestContext, Guid pluginAssemblyId, Int32 sourceHash, String assemblyName, Guid pluginTypeId, String pluginTypeName, String pluginConfiguration, String pluginSecureConfig, Boolean returnTraceInfo, Int64&amp; wcfExecInMs, Int64&amp; initializeInMs, Int64&amp; trackCallInMs, Int64&amp; trackGoodReturnInMs, Int64&amp; waitInMs, Int64&amp; taskStartDelay)</OriginalException>
  <TraceText i:nil="true" />
</OrganizationServiceFault>

Рабочий процесс достигает предела памяти

Каждый рабочий процесс имеет ограниченный объем памяти. Существуют условия, в которых несколько параллельных операций, включающих большие объемы данных, могут превышать доступную память и привести к сбою рабочего процесса.

ПолучениеMultiple с данными файла

Распространенный сценарий в этом случае заключается в том, что подключаемый модуль выполняется для RetrieveMultiple операции, в которой запрос содержит данные файла. Например, при получении сообщений электронной почты, включающих вложения файлов. Объем данных, которые могут быть возвращены в запросе, непредсказуем, так как любая электронная почта может быть связана с любым количеством вложений файлов, а вложения могут отличаться в размере.

При одновременном выполнении нескольких запросов аналогичной природы объем памяти становится большим. Если объем памяти превышает предел, процесс завершается сбоем. Ключевым фактором предотвращения этой ситуации является ограничение RetrieveMultiple запросов, включающих сущности со связанными вложениями файлов. Извлеките записи с помощью RetrieveMultiple, но извлеките все связанные файлы при необходимости с помощью отдельных Retrieve операций.

Утечки памяти

Менее распространенный сценарий заключается в том, что код в подключаемом модуле утечки памяти. Эта ситуация может возникать, когда подключаемый модуль не записывается как без отслеживания состояния, что является другой лучшей практикой. Дополнительные сведения см. в разделе "Разработка реализаций подключаемых модулей как без отслеживания состояния". Если подключаемый модуль не находится в состоянии без отслеживания состояния, и есть попытка постоянно добавлять данные в свойство с отслеживанием состояния, например массив, объем данных увеличивается до точки, где она использует всю доступную память.

Ошибки транзакции

Существует два распространенных типа ошибок, связанных с транзакциями:

Код ошибки: -2146893812
Сообщение об ошибке: код ISV сократил число открытых транзакций. Пользовательские подключаемые модули не должны перехватывать исключения из вызовов OrganizationService и продолжать обработку.

Код ошибки: -2147220911
Сообщение об ошибке: нет активной транзакции. Эта ошибка обычно вызвана пользовательскими подключаемыми модулями, которые игнорируют ошибки из вызовов служб и продолжают обработку.

Примечание.

Последняя ошибка была добавлена. Оно должно происходить немедленно и в контексте подключаемого модуля, содержащего проблему. Нижняя ошибка по-прежнему может возникать в различных обстоятельствах, обычно с участием пользовательских действий рабочего процесса. Это может быть связано с проблемами в другом подключаемом модуле.

В любой момент, когда ошибка, связанная с операцией данных, возникает в синхронном подключаемом модуле, транзакция для всей операции завершается.

Дополнительные сведения см. в статье "Масштабируемая настройка" в Microsoft Dataverse.

Распространенная причина заключается в том, что разработчик считает, что он может попытаться выполнить операцию, которая может завершиться успешно, поэтому они упаковывают операцию вcatch try/блок и пытаются проглотить ошибку при сбое.

Хотя этот шаблон может работать для клиентского приложения, в рамках выполнения подключаемого модуля любая операция данных приводит к откату всей транзакции. Не удается проглотить ошибку, поэтому обязательно всегда возвращать InvalidPluginExecutionExceptionобъект.

Ошибка "Ошибка SQL: истекло время ожидания выполнения"

Код ошибки: -2147204783
Сообщение об ошибке: ошибка SQL: "Истекло время ожидания выполнения. Период времени ожидания истек до завершения операции или сервер не отвечает.

Причина

Существует множество причин, по которым может возникнуть ошибка времени ожидания SQL. Три из них описаны здесь:

Блокировка

Наиболее распространенной причиной ошибки времени ожидания SQL является ожидание ресурсов, заблокированных другой транзакцией SQL. Ошибка — это результат защиты целостности данных и от длительных запросов, влияющих на производительность для пользователей.

Блокировка может быть вызвана другими параллельными операциями. Код может работать в изоляции в тестовой среде и по-прежнему подвержены условиям, которые возникают только в том случае, если несколько пользователей инициируют логику в подключаемом модуле.

При написании подключаемых модулей важно понять, как разрабатывать настройки, которые являются масштабируемыми. Дополнительные сведения см. в разделе "Масштабируемая настройка" в Dataverse.

Каскадные операции

Некоторые действия, которые вы выполняете в подключаемом модуле, например назначение или удаление записи, могут инициировать каскадные операции с связанными записями. Эти действия могут применять блокировки к связанным записям, что приводит к блокировке последующих операций с данными, что, в свою очередь, может привести к истечении времени ожидания SQL.

Следует рассмотреть возможные последствия этих каскадных операций с операциями с данными в подключаемом модуле. Дополнительные сведения см. в разделе "Поведение связей таблиц".

Так как эти поведения могут быть настроены по-разному между средами, поведение может быть трудно воспроизвести, если среды не настроены таким же образом.

Индексы в новых таблицах

Если подключаемый модуль выполняет операции с помощью таблицы или столбца, созданного недавно, некоторые возможности SQL Azure для управления индексами могут измениться через несколько дней.

Ошибки из-за привилегий пользователей

В клиентском приложении можно отключить команды, которые пользователи не могут выполнять. В подключаемом модуле у вас нет этой возможности. Код может включать в себя некоторую автоматизацию, которую вызывающий пользователь не имеет привилегий для выполнения.

Подключаемый модуль можно зарегистрировать для запуска в контексте пользователя, известного как правильные привилегии, задав для этого пользователя значение запуска в контексте пользователя. Или можно выполнить операцию, олицетворив другого пользователя. Дополнительные сведения см. в разделе:

Ошибка при выполнении в контексте отключенного пользователя

При выполнении подключаемого модуля в контексте отключенного пользователя возвращается следующая ошибка:

Сообщение об ошибке: System.ServiceModel.FaultException'1[Microsoft.Xrm.Sdk.OrganizationServiceFault]: пользователь с SystemUserId=<User-ID> в OrganizationContext=<Context> отключен. Отключенные пользователи не могут получить доступ к системе. Рассмотрите возможность включения этого пользователя. Кроме того, пользователи отключены, если у них нет лицензии.

Чтобы устранить эту ошибку, можно выполнить запрос, чтобы найти шаги, зарегистрированные для отключенного пользователя, а также связанные подключаемые модули и SdkMessage сведения.

https://<env-url>/api/data/v9.2/sdkmessageprocessingsteps
?$filter=_impersonatinguserid_value eq '<disabled-userId-from-error>'&
$expand=plugintypeid($select=name,friendlyname,assemblyname;
$expand=pluginassemblyid($select=solutionid,name,isolationmode)),sdkmessageid($select=solutionid,name)&
$select=solutionid,name,stage,_impersonatinguserid_value,mode

Ошибка "Размер сообщения превышен при отправке контекста в песочницу"

Код ошибки: -2147220970
Сообщение об ошибке: размер сообщения превышается при отправке контекста в песочницу. Размер сообщения: ### Mb

Эта ошибка возникает, когда полезные данные сообщения больше 116,85 МБ, а подключаемый модуль регистрируется для сообщения. Сообщение об ошибке содержит размер полезных данных, вызвавших эту ошибку.

Ограничение помогает гарантировать, что пользователи, работающие в приложениях, не могут мешать друг другу на основе ограничений ресурсов. Ограничение помогает обеспечить уровень защиты от необычно больших полезных данных сообщений, которые угрожают доступности и производительности платформы Dataverse.

116,85 МБ достаточно большой, что это должно быть редко, чтобы столкнуться с этим случаем. Наиболее вероятной ситуацией, когда этот случай может возникнуть при получении записи с несколькими связанными записями, включающими большие двоичные файлы.

Если вы получите эту ошибку, вы можете:

  1. Удалите подключаемый модуль для сообщения. Если для сообщения нет подключаемых модулей, операция завершается без ошибки.
  2. Если ошибка возникает в пользовательском клиенте, можно изменить код таким образом, чтобы он не пытался выполнить работу в одной операции. Вместо этого напишите код для получения данных в небольших частях.

Ошибка "Заданный ключ не был представлен в словаре"

Dataverse часто использует классы, производные от абстрактного DataCollection<TKey,TValue> класса, представляющего коллекцию ключей и значений. Например, с подключаемыми модулями IExecutionContextсвойство .InputParameters является производным ParameterCollection от DataCollection<TKey,TValue> класса. Эти классы по сути являются объектами словаря, в которых вы обращаетесь к определенному значению с помощью имени ключа.

Коды ошибок

Эта ошибка возникает, когда значение ключа в коде не существует в коллекции. Результатом является ошибка во время выполнения, а не ошибка платформы. Если эта ошибка возникает в подключаемом модуле, код ошибки зависит от того, была ли обнаружена ошибка.

Если разработчик поймал исключение и вернулся InvalidPluginExecutionException, как описано в разделе "Обработка исключений в подключаемых модулях", возвращается следующая ошибка:

Код ошибки: -2147220891
Сообщение об ошибке: код ISV прерван операции.

Однако при этой ошибке обычно разработчик не перехватывает его должным образом, и возвращается следующая ошибка:

Код ошибки: -2147220956
Сообщение об ошибке: произошла непредвиденная ошибка из кода ISV.

Примечание.

IsV означает независимых поставщиков программного обеспечения.

Причина

Эта ошибка часто возникает во время разработки и может возникать из-за ошибки или использования неправильного регистра. Ключевые значения чувствительны к регистру.

Во время выполнения ошибка часто возникает из-за того, что разработчик предполагает, что значение присутствует, если оно отсутствует. Например, в подключаемом модуле, зарегистрированном для обновления таблицы, в коллекцию включены EntityAttributes только те значения, которые изменились.

Решение

Чтобы устранить эту ошибку, необходимо проверить, существует ли ключ, прежде чем пытаться использовать его для доступа к значению.

Например, при доступе к столбцу таблицы можно использовать Entityметод .Contains(String) для проверки наличия столбца в таблице, как показано в следующем коде.

// Obtain the execution context from the service provider.  
IPluginExecutionContext context = (IPluginExecutionContext)
    serviceProvider.GetService(typeof(IPluginExecutionContext));

// The InputParameters collection contains all the data passed in the message request.  
if (context.InputParameters.Contains("Target") &&
    context.InputParameters["Target"] is Entity)
    {
    // Obtain the target entity from the input parameters.  
    Entity entity = (Entity)context.InputParameters["Target"];

    //Check whether the name attribute exists.
    if(entity.Contains("name"))
    {
        string name = entity["name"];
    }

Некоторые разработчики используют Entityметод .GetAttributeValue<T>(String) , чтобы избежать этой ошибки при доступе к столбцу таблицы. Этот метод возвращает значение по умолчанию типа, если столбец не существует. Если значение по умолчанию равно NULL, этот метод работает должным образом. Но если значение по умолчанию не возвращает значение NULL, например с параметром DateTime, возвращаемое 1/1/0001 00:00 значение вместо NULL.

Ошибка "Не удается запустить транзакцию с другим уровнем изоляции, чем уже задано в текущей транзакции".

Код ошибки: -2147220989
Сообщение об ошибке: вы не можете запустить транзакцию с другим уровнем изоляции, чем уже задано в текущей транзакции.

Подключаемые модули предназначены для поддержки бизнес-логики. Изменение любой части схемы данных в синхронном подключаемом модуле не поддерживается. Эти операции часто занимают больше времени и могут привести к тому, что кэшированные метаданные, используемые приложениями, перестают синхронизироваться. Однако эти операции можно выполнять в шаге подключаемого модуля, зарегистрированном для асинхронного выполнения.

Известная проблема: значение имени Activity.RegardingObjectId не задано с подключаемым модулем

Наиболее распространенным признаком этой проблемы является то, что поле "Относительно " в записи действий показывает (No Name) , а не значение атрибута первичного имени.

В подключаемом модуле можно задать атрибуты подстановки со значением EntityReference . Свойство EntityReference.Name не требуется. Как правило, его не нужно включать при настройке значения атрибута подстановки, так как Dataverse задает его. Значения, подобные этому, следует задать во время этапа preOperation конвейера событий. Дополнительные сведения см. в разделе конвейера выполнения событий.

Исключение из этого правила заключается в настройке подстановки ActivityPointer.RegardingObjectId . Все типы сущностей, производные от ActivityPointer наследуемой этой подстановки. По умолчанию они включают встречи, чат, электронную почту, факс, письмо, PhoneCall, ПовторяющийсяAppointmentMaster и все пользовательские таблицы, созданные в качестве типов действий. Дополнительные сведения см. в таблицах действий.

Если задать это значение на этапе PreOperation , значение имени не добавляется Dataverse. Значение равно NULL, а форматируемое значение, которое должно содержать это значение, не присутствует при получении записи.

Обходное решение

Существует два способа решения этой проблемы:

  1. Можно задать значение свойства EntityReference.Name с правильным значением поля основного имени перед заданием значения атрибута подстановки.
  2. Значение подстановки можно задать на этапе предварительной подготовки , а не на этапе предварительной операции.

Дополнительная информация