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


Устранение неполадок с подключаемыми модулями 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 ошибки возвращается агрегатное исключение. Объединяет 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.Plugin.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"
    }
}

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

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>

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

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

RetrieveMultiple с данными файла

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

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

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

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

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

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

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

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

Примечание.

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

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

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

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

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

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

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

Причина

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

Блокировки

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Сообщение об ошибке: 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
Сообщение об ошибке: код поставщика программного обеспечения прерван операцию.

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

Код ошибки: -2147220956
Сообщение об ошибке: произошла непредвиденная ошибка в коде независимого поставщика программного обеспечения.

Примечание.

"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 этого, наследуют этот поиск. По умолчанию к ним относятся appointment, chat, Email, Fax, Letter, PhoneCall, RecurringAppointmentMaster и все пользовательские таблицы, созданные в качестве типов действий. Дополнительные сведения см. в разделе Таблицы действий.

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

Обходной путь

Эту проблему можно обойти двумя способами:

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

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