Solución de problemas de complementos de Dataverse

Este artículo contiene información sobre los errores que pueden producirse durante la ejecución del complemento o los errores de Dataverse relacionados con los complementos y cómo evitarlos o corregirlos.

Error "No se pudo completar la conversión de tiempo"

Código de error: -2147220956
Mensaje de error: No se pudo completar la conversión porque datatime proporcionado no tenía la propiedad Kind establecida correctamente. Por ejemplo, cuando la propiedad Kind es DateTimeKind.Local, la zona horaria de origen debe ser TimeZoneInfo.Local.

Este error puede producirse durante una TimeZoneInfo.ConvertTimeToUtc(DateTime, TimeZoneInfo) llamada en el código del complemento para convertir un DateTime valor en la zona horaria de Santiago o Volgograd a la hora universal coordinada (UTC).

Este error se debe a una limitación conocida del producto y actualmente no hay ninguna solución alternativa.

Para obtener más información, vea Especificar la configuración de zona horaria para un usuario.

Error "Se bloqueó el proceso de trabajo del espacio aislado"

Código de error: -2147204723
Mensaje de error: Error en la ejecución del complemento porque el proceso de trabajo de espacio aislado se bloqueó. Esto suele deberse a un error en el código del complemento.

Este error simplemente significa que el proceso de trabajo que ejecuta el código del complemento se bloqueó. El complemento podría ser el motivo del bloqueo, pero también podría ser otro complemento que se ejecuta simultáneamente para su organización. Dado que el proceso se bloqueó, no podemos extraer información más específica sobre por qué se bloqueó. Pero después de examinar los datos de los volcados de memoria después del hecho, encontramos que este error suele producirse debido a una de las cuatro razones:

Excepción no controlada en el complemento

Al escribir un complemento, debe intentar anticipar qué operaciones podrían producir un error y encapsularlas en un bloque try-catch. Cuando se produce un error, debe usar la InvalidPluginExecutionException clase para finalizar correctamente la operación con un error significativo para el usuario.

Para obtener más información, consulte Control de excepciones en complementos.

Un escenario común para esta excepción es cuando se usa el método HttpClient.SendAsync o HttpClient.GetAsync . Estos métodos HttpClient son operaciones asincrónicas que devuelven una tarea. Para trabajar en un complemento en el que el código debe ser sincrónico, los usuarios pueden usar el TResult> de tarea<. Result (propiedad). Cuando se produce un error, Result devuelve una excepción AggregateException. un AggregateException consolida varios errores en una sola excepción, lo que puede ser difícil de controlar. Un mejor diseño consiste en usar TResult> de tarea<. GetAwaiter(). GetResult() porque propaga los resultados como el error específico que provocó el error.

En el ejemplo siguiente se muestra la manera correcta de administrar la excepción y una llamada saliente mediante el método HttpClient.GetAsync . Este complemento intenta obtener el texto de respuesta de un uri establecido en la configuración no segura para un paso registrado para él.

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

Uso de subprocesos para poner en cola el trabajo sin try/catch en el delegado de subprocesos

No debe usar patrones de ejecución en paralelo en complementos. Este antipatrón se describe en el artículo de procedimientos recomendados: No usar la ejecución en paralelo dentro de complementos y actividades de flujo de trabajo. El uso de estos patrones puede provocar problemas al administrar la transacción en un complemento sincrónico. Sin embargo, otra razón para no usar estos patrones es que cualquier trabajo realizado fuera de un try/catch bloque en un delegado de subproceso puede bloquear el proceso de trabajo.

Importante

Cuando se bloquea el proceso de trabajo, la ejecución del complemento y otros complementos que se ejecutan actualmente en ese proceso finalizarán. Esto incluye complementos que no posee ni mantiene.

Application Insights para el rescate

En el pasado, era imposible obtener el seguimiento de la pila u otra información de ejecución para excepciones de complementos no controladas del proceso de trabajo bloqueado. Sin embargo, Dataverse ahora ofrece compatibilidad para registrar errores de ejecución en Application Insights. Para habilitar esta función, puede vincular Application Insights al entorno donde está registrado el complemento. Una vez vinculado, el registro del complemento se bloquea automáticamente.

Para obtener más información, consulte Exportación de datos a Application Insights.

Una vez vinculado un entorno de Application Insights, estarán disponibles los siguientes datos de un bloqueo del proceso de trabajo para solucionar el problema.

Ejemplo de un informe de bloqueo de complemento de Application Insights.

Para ir al informe de bloqueo en Application Insights, siga estos pasos:

  1. Vincule Application Insights a su entorno.
  2. Espere hasta que una excepción de complemento genere el error de bloqueo del proceso de trabajo.
  3. En el Centro de administración de Power Platform, vaya a Application Insights.
  4. En la página Application Insights, seleccione Errores en el panel izquierdo.
  5. En la página Errores , seleccione Excepciones.
  6. En Id. de problema de excepción, en la lista General , seleccione Microsoft.PowerPlatform.Dataverse.Plugin.PluginWorkerCrashException.
  7. En el lado derecho de la página, en General, seleccione PluginWorkerCrashException. Ahora verá los detalles de todas las excepciones de bloqueo del proceso de trabajo registradas.
  8. Búsqueda y seleccione la excepción deseada en el panel izquierdo y el informe de detalles de la excepción se mostrará en el lado derecho de la página (vea la captura de pantalla anterior para obtener un ejemplo).
  9. Para acceder al seguimiento de la pila, expanda CrashDetails en el informe.

Error de desbordamiento de pila en el complemento

Este tipo de error se produce con más frecuencia justo después de realizar algunos cambios en el código del complemento. Algunas personas usan su propio conjunto de clases base para simplificar su experiencia de desarrollo. A veces, estos errores se originan a partir de cambios en las clases base de las que depende un complemento determinado.

Por ejemplo, una llamada recursiva sin una condición de terminación o una condición de terminación, que no cubre todos los escenarios, puede hacer que se produzca este error. Para obtener más información, vea StackOverflowException (Comentarios de clase>).

Debe revisar los cambios de código que se aplicaron recientemente para el complemento y cualquier otro código del que dependa el código del complemento.

Ejemplo:

El siguiente código de complemento provoca un StackOverflowException debido a una llamada recursiva sin límites. A pesar del uso del seguimiento y de intentar capturar el error, el seguimiento y el error no se devuelven porque el proceso de trabajo que los procesaría terminó.

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

En un paso de complemento sincrónico, el código de complemento mostrado anteriormente devuelve el siguiente error en la API web cuando la solicitud está configurada para incluir detalles adicionales con errores.

{
    "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"
    }
}

A continuación se muestra cómo se registra este error en el registro de seguimiento del complemento:

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>

El proceso de trabajo alcanza el límite de memoria

Cada proceso de trabajo tiene una cantidad finita de memoria. Hay condiciones en las que varias operaciones simultáneas que incluyen grandes cantidades de datos podrían superar la memoria disponible y hacer que el trabajo de proceso se bloquee.

RetrieveMultiple con datos de archivo

El escenario común, en este caso, es cuando se ejecuta un complemento para una RetrieveMultiple operación en la que la solicitud incluye datos de archivo. Por ejemplo, al recuperar correos electrónicos que incluyen datos adjuntos de archivos. La cantidad de datos que se pueden devolver en una consulta como esta es impredecible porque cualquier correo electrónico puede estar relacionado con cualquier número de datos adjuntos de archivo y los datos adjuntos pueden variar en tamaño.

Cuando varias solicitudes de una naturaleza similar se ejecutan simultáneamente, la cantidad de memoria necesaria se vuelve grande. Si la cantidad de memoria supera el límite, el proceso se bloquea. La clave para evitar esta situación es limitar RetrieveMultiple las consultas que incluyen entidades con datos adjuntos de archivos relacionados. Recupere los registros mediante RetrieveMultiple, pero recupere los archivos relacionados según sea necesario mediante operaciones individuales Retrieve .

Pérdidas de memoria

Un escenario menos común es donde el código del complemento pierde memoria. Esta situación puede producirse cuando el complemento no se escribe como sin estado, lo que es otro procedimiento recomendado. Para obtener más información, consulte Desarrollo de implementaciones de complementos como sin estado. Cuando el complemento no tiene estado y se intenta agregar continuamente datos a una propiedad con estado como una matriz, la cantidad de datos aumenta hasta el punto en que usa toda la memoria disponible.

Errores de transacción

Hay dos tipos comunes de errores relacionados con las transacciones:

Código de error: -2146893812
Mensaje de error: el código ISV ha reducido el número de transacciones abiertas. Los complementos personalizados no deben detectar excepciones de llamadas OrganizationService y continuar el procesamiento.

Código de error: -2147220911
Mensaje de error: no hay ninguna transacción activa. Este error suele deberse a complementos personalizados que omiten los errores de las llamadas de servicio y continúan el procesamiento.

Nota:

El error superior se agregó más recientemente. Debe producirse inmediatamente y en el contexto del complemento que contiene el problema. El error inferior todavía puede producirse en circunstancias diferentes, normalmente relacionadas con actividades de flujo de trabajo personalizadas. Puede deberse a problemas en otro complemento.

Cada vez que se produce un error relacionado con una operación de datos dentro de un complemento sincrónico, finaliza la transacción de toda la operación.

Para obtener más información, vea Diseño de personalización escalable en Microsoft Dataverse.

Una causa común es que un desarrollador cree que puede intentar realizar una operación que podría tener éxito, por lo que encapsulan esa operación en un bloque e intentan tragar el error cuando se produce un try/catch error.

Aunque este patrón puede funcionar para una aplicación cliente, dentro de la ejecución de un complemento, cualquier error de operación de datos da como resultado revertir toda la transacción. No puede tragar el error, por lo que debe asegurarse de devolver siempre un InvalidPluginExecutionExceptionobjeto .

Error "Error de Sql: Tiempo de espera de ejecución expirado"

Código de error: -2147204783
Mensaje de error: Error de SQL: 'Tiempo de espera de ejecución expirado. El período de tiempo de espera transcurrido antes de la finalización de la operación o el servidor no responde."

Causa

Hay una amplia variedad de razones por las que se puede producir un error de tiempo de espera de SQL. Tres de ellas se describen aquí:

Bloqueo

La causa más común de un error de tiempo de espera de SQL es que la operación está esperando a que otra transacción de SQL bloquee los recursos. El error es el resultado de que Dataverse protege la integridad de los datos y de las solicitudes de ejecución prolongada que afectan al rendimiento de los usuarios.

El bloqueo puede deberse a otras operaciones simultáneas. El código podría funcionar bien de forma aislada en un entorno de prueba y seguir siendo susceptible a condiciones que solo se producen cuando varios usuarios inician la lógica en el complemento.

Al escribir complementos, es esencial comprender cómo diseñar personalizaciones escalables. Para obtener más información, vea Diseño de personalización escalable en dataverse.

Operaciones en cascada

Ciertas acciones que realice en el complemento, como asignar o eliminar un registro, pueden iniciar operaciones en cascada en registros relacionados. Estas acciones podrían aplicar bloqueos en registros relacionados que provocarán el bloqueo de las operaciones de datos posteriores, lo que a su vez puede provocar un tiempo de espera de SQL.

Debe tener en cuenta el posible impacto de estas operaciones en cascada en las operaciones de datos del complemento. Para obtener más información, vea Comportamiento de la relación de tabla.

Dado que estos comportamientos se pueden configurar de forma diferente entre entornos, el comportamiento puede ser difícil de reproducir a menos que los entornos estén configurados de la misma manera.

Índices en tablas nuevas

Si el complemento realiza operaciones con una tabla o columna que se creó recientemente, algunas funcionalidades de Azure SQL para administrar índices podrían marcar una diferencia después de unos días.

Errores debidos a privilegios de usuario

En una aplicación cliente, puede deshabilitar los comandos que los usuarios no pueden realizar. Dentro de un complemento, no tiene esta capacidad. El código puede incluir alguna automatización que el usuario que realiza la llamada no tiene los privilegios que se deben realizar.

Puede registrar el complemento para que se ejecute en el contexto de un usuario que tenga los privilegios correctos estableciendo el valor Ejecutar en el contexto del usuario en ese usuario. O bien, puede ejecutar la operación suplantando a otro usuario. Para obtener más información, consulte:

Error al ejecutar en el contexto de un usuario deshabilitado

Cuando se ejecuta un complemento en el contexto de un usuario deshabilitado, se devuelve el siguiente error:

Mensaje de error: System.ServiceModel.FaultException'1[Microsoft.Xrm.Sdk.OrganizationServiceFault]: El usuario con SystemUserId=<User-ID> en OrganizationContext=<Context> está deshabilitado. Los usuarios deshabilitados no pueden acceder al sistema. Considere la posibilidad de habilitar este usuario. Además, los usuarios se deshabilitan si no tienen una licencia asignada.

Para solucionar este error, puede ejecutar una consulta para buscar los pasos registrados en el usuario deshabilitado, así como el complemento y SdkMessage los detalles asociados.

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

Error "Se superó el tamaño del mensaje al enviar contexto al espacio aislado"

Código de error: -2147220970
Mensaje de error: se superó el tamaño del mensaje al enviar contexto al espacio aislado. Tamaño del mensaje: ### Mb

Este error se produce cuando una carga del mensaje es mayor que 116,85 MB y se registra un complemento para el mensaje. El mensaje de error incluye el tamaño de la carga que produjo este error.

El límite ayuda a garantizar que los usuarios que ejecutan aplicaciones no puedan interferir entre sí en función de las restricciones de recursos. El límite ayuda a proporcionar un nivel de protección frente a cargas de mensajes inusualmente grandes que amenazan las características de disponibilidad y rendimiento de la plataforma Dataverse.

116,85 MB es lo suficientemente grande como para que sea raro encontrar este caso. La situación más probable en la que podría producirse este caso es cuando se recupera un registro con varios registros relacionados que incluyen archivos binarios grandes.

Si recibe este error, puede:

  1. Quite el complemento para el mensaje. Si no hay ningún complemento registrado para el mensaje, la operación se completa sin ningún error.
  2. Si el error se produce en un cliente personalizado, puede modificar el código para que no intente realizar el trabajo en una sola operación. En su lugar, escriba código para recuperar los datos en partes más pequeñas.

Error "La clave dada no estaba presente en el diccionario"

Dataverse usa con frecuencia clases derivadas de la clase abstracta DataCollection<TKey,TValue> que representa una colección de claves y valores. Por ejemplo, con complementos, la IExecutionContextpropiedad .InputParameters es una ParameterCollection derivada de la DataCollection<TKey,TValue> clase . Estas clases son básicamente objetos de diccionario en los que se accede a un valor específico mediante el nombre de clave.

Códigos de error

Este error se produce cuando el valor de clave del código no existe en la colección. El resultado es un error en tiempo de ejecución en lugar de un error de plataforma. Cuando este error se produce dentro de un complemento, el código de error depende de si se detectó el error.

Si el desarrollador detectó la excepción y devolvió InvalidPluginExecutionException, como se describe en Control de excepciones en complementos, se devuelve el siguiente error:

Código de error: -2147220891
Mensaje de error: el código ISV anuló la operación.

Sin embargo, con este error, es habitual que el desarrollador no lo detecte correctamente y se devuelva el siguiente error:

Código de error: -2147220956
Mensaje de error: Error inesperado del código ISV.

Nota:

"ISV" significa Proveedor de software independiente.

Causa

Este error se produce con frecuencia en tiempo de diseño y puede deberse a un error ortográfico o al uso de mayúsculas y minúsculas incorrectas. Los valores de clave distinguen mayúsculas de minúsculas.

En tiempo de ejecución, el error suele deberse a que el desarrollador asume que el valor está presente cuando no lo está. Por ejemplo, en un complemento registrado para la actualización de una tabla, solo se incluyen en la Entitycolección .Attributes

Solución

Para resolver este error, debe comprobar que la clave existe antes de intentar usarla para acceder a un valor.

Por ejemplo, al acceder a una columna de tabla, puede usar el Entitymétodo .Contains(String) para comprobar si existe una columna en una tabla, como se muestra en el código siguiente.

// 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"];
    }

Algunos desarrolladores usan el Entitymétodo .GetAttributeValue<T>(String) para evitar este error al acceder a una columna de tabla. Este método devuelve el valor predeterminado del tipo si la columna no existe. Si el valor predeterminado es NULL, este método funciona según lo esperado. Pero si el valor predeterminado no devuelve null, como con , DateTimeel valor devuelto es 1/1/0001 00:00 en lugar de null.

Error "No se puede iniciar una transacción con un nivel de aislamiento diferente al que ya está establecido en la transacción actual"

Código de error: -2147220989
Mensaje de error: No se puede iniciar una transacción con un nivel de aislamiento diferente al que ya está establecido en la transacción actual.

Los complementos están diseñados para admitir la lógica de negocios. No se admite la modificación de ninguna parte del esquema de datos dentro de un complemento sincrónico. Estas operaciones suelen tardar más tiempo y pueden hacer que los metadatos almacenados en caché que usan las aplicaciones se quediquen de sincronizarse. Sin embargo, estas operaciones se pueden realizar en un paso de complemento registrado para ejecutarse de forma asincrónica.

Problema conocido: El valor del nombre Activity.RegardingObjectId no se establece con el complemento

El síntoma más común de este problema es que el campo Regarding de un registro de actividad muestra (No Name) en lugar del valor del atributo de nombre principal.

Dentro de un complemento, puede establecer atributos de búsqueda con un valor EntityReference . La propiedad EntityReference.Name no es necesaria. Normalmente, no es necesario incluirlo al establecer un valor de atributo de búsqueda porque Dataverse lo establece. Debe establecer valores como este durante la fase PreOperation de la canalización de eventos. Para obtener más información, vea Canalización de ejecución de eventos.

La excepción a esta regla es al establecer la búsqueda ActivityPointer.RegardingObjectId . Todos los tipos de entidad que se derivan de ActivityPointer heredan esta búsqueda. De forma predeterminada, estos incluyen Appointment, Chat, Email, Fax, Letter, PhoneCall, RecurringAppointmentMaster y todas las tablas personalizadas que se crearon como tipos de actividad. Para obtener más información, vea Tablas de actividad.

Si establece este valor en la fase PreOperation , Dataverse no agrega el valor de nombre. El valor es null y el valor con formato que debe contener este valor no está presente cuando se recupera el registro.

Solución alternativa

Hay dos maneras de solucionar este problema:

  1. Puede establecer el valor de la propiedad EntityReference.Name con el valor de campo de nombre principal correcto antes de establecer el valor del atributo de búsqueda.
  2. Puede establecer el valor de búsqueda en la fase PreValidation en lugar de en la fase PreOperation .

Más información