Compartir a través de


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 Santiago o Volgograd a hora universal coordinada (UTC).

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

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

Error "Proceso de trabajo de espacio aislado bloqueado"

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

Este error significa simplemente que se ha bloqueado el proceso de trabajo que ejecuta el código de complemento. 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 errores 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 Controlar 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, es posible que los usuarios usen el TResult> de la tarea<. Propiedad Result. Cuando se produce un error, Result devuelve aggregateException. Un AggregateException consolida varios errores en una única excepción, lo que puede ser difícil de controlar. Es mejor usar el diseño Task<TResult>.GetAwaiter().GetResult() porque propaga los resultados como el error específico que causó 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 de 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 bloque try/catch en el delegado de subproceso

No debe usar patrones de ejecución en paralelo en complementos. Este antipatrón se llama en el artículo de procedimientos recomendados: No use 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 bloque de un try/catch delegado de subprocesos puede bloquear el proceso de trabajo.

Importante

Cuando el proceso de trabajo se bloquea, 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, la obtención del seguimiento de la pila u otra información de ejecución para excepciones de complemento no controladas del proceso de trabajo bloqueado era imposible. Sin embargo, Dataverse ahora ofrece compatibilidad con errores de ejecución de registro en Application Insights. Para habilitar esta función, puede vincular Application Insights al entorno donde está registrado el complemento. Una vez vinculado, el registro de bloqueos del complemento se produce automáticamente.

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

Una vez vinculado un entorno de Application Insights, los siguientes datos de un bloqueo de proceso de trabajo estarán disponibles 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 produzca 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 registrados.
  8. Busque y seleccione la excepción deseada en el panel izquierdo y el informe de detalles de excepciones se mostrará en el lado derecho de la página (consulte 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 después de realizar algunos cambios en el código del complemento. Algunas personas usan su propio conjunto de clases base para optimizar su experiencia de desarrollo. A veces, estos errores se originan por cambios en las clases base de las que depende un complemento concreto.

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 provocar este error. Para obtener más información, consulte Comentarios de la clase > StackOverflowException.

Debe revisar los cambios de código que se hayan aplicado recientemente al complemento y cualquier otro código del que dependa el código del complemento.

Ejemplo

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

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 del 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 complemento 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>

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 exceder la memoria disponible y provocar el bloqueo del proceso de trabajo.

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 incluyan datos adjuntos de archivo. La cantidad de datos que se pueden devolver en una consulta como esta es impredecible, ya que cualquier correo electrónico podría estar relacionado con cualquier número de datos adjuntos de archivo y los datos adjuntos pueden variar en tamaño.

Cuando se ejecutan simultáneamente varias solicitudes de naturaleza similar, la cantidad de memoria se hace 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 con RetrieveMultiple, pero debe recuperar los archivos relacionados a medida que sea necesario mediante operaciones Retrieve.

Pérdidas de memoria

Un escenario menos común es cuando el código del complemento pierde memoria. Esta situación puede producirse cuando el complemento no está escrito como sin estado, 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 hay un intento de agregar datos continuamente a una propiedad con estado como una matriz, la cantidad de datos crece 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 redujo el recuento 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 procesando.

Nota:

El error principal se agregó más recientemente. Debe aparecer inmediatamente y en el contexto del complemento que contiene el problema. El error inferior todavía puede aparecer en diferentes circunstancias, implicando normalmente actividades personalizadas del flujo de trabajo. 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, se 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 pueda realizarse correctamente, por lo que encapsula esa operación en uncatch try/bloque e intenta tragar el error cuando se produce un 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 se puede tragar el error, por lo que debe asegurarse de siempre devolver un InvalidPluginExecutionException.

Error "Error 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 puede producirse un error de tiempo de espera de SQL. Aquí se describen tres de ellas:

Bloqueos

La causa más común de un error de tiempo de espera de SQL es que la operación está esperando recursos bloqueados por otra transacción SQL. El error es el resultado de Dataverse que 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 puede funcionar correctamente de forma aislada en un entorno de prueba y seguir siendo susceptible a las condiciones que solo se producen cuando varios usuarios inician la lógica en el complemento.

Al escribir complementos, es importante comprender cómo diseñar personalizaciones que sean escalables. Para obtener más información, consulte Diseño de personalización escalable en Dataverse.

Operaciones en cascada

Algunas acciones que usted realiza en el complemento, como asignar o eliminar un registro, pueden iniciar operaciones en cascada en los registros relacionados. Estas acciones podrían aplicar bloqueos en registros relacionados que hacen que se bloqueen las operaciones de datos posteriores, lo que a su vez puede dar lugar a un tiempo de espera de SQL.

Debe considerar el impacto posible de estas operaciones en cascada en las operaciones de datos del complemento. Para obtener más información, consulte Comportamiento de las relaciones 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 está realizando operaciones mediante una tabla o columna que se creó recientemente, algunas funcionalidades de Azure SQL para administrar índices podrían marcar la 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 cierta automatización que el usuario que realiza la llamada no tiene los privilegios para realizar.

Puede registrar el complemento para ejecutarse en el contexto de un usuario conocido para tener los privilegios correctos estableciendo el valor Ejecutar en contexto de usuario a ese usuario. O bien, puede ejecutar la operación suplantando a otro usuario. Para más información, vea:

Error al ejecutarse 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 asociado y SdkMessage los detalles.

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 de mensajes es superior a 116,85 MB y se registra un complemento para el mensaje. El mensaje de error incluye el tamaño de la carga que provocó 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 de Dataverse.

116,85 MB es bastante grande, por lo que debería ser raro que se produzca este caso. La situación más probable donde puede producirse este caso es cuando se recupera un registro con varios registros relacionados que incluyen archivos binarios grandes.

Si recibe este error, puede hacer lo siguiente:

  1. Quitar el complemento del mensaje. Si no hay complementos registrados para el mensaje, la operación se completa sin un error.
  2. Si el error se produce en un cliente personalizado, puede modificar el código de forma que no intente realizar el trabajo en una sola operación. En su lugar, escriba código para recuperar los datos en partes menores.

Error "La clave especificada 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 se ParameterCollection deriva de la DataCollection<TKey,TValue> clase . Estas clases son esencialmente objetos de diccionario en las que puede tener acceso a un valor específico con 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 Controlar 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 detecta correctamente y se devuelve el siguiente error:

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

Nota:

"ISV" son las siglas de Fabricante independiente de software.

Causa

Este error aparece con frecuencia en tiempo de diseño y puede deberse a la falta de ortografía o al uso incorrecto de mayúsculas y minúsculas. Los valores de clave distinguen mayúsculas de minúsculas.

En tiempo de ejecución, el error suele deberse al desarrollador, suponiendo que el valor esté presente cuando no lo sea. Por ejemplo, en un complemento registrado para la actualización de una tabla, solo los valores que se cambian 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 previsto. 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 destinados a admitir la lógica empresarial. No se admite la modificación de cualquier parte del esquema de datos dentro de un complemento sincrónico. Estas operaciones tardan más tiempo y pueden provocar que las aplicaciones no se sincronicen los metadatos almacenados en caché. Sin embargo, estas operaciones se pueden realizar en un paso de complemento registrado para ejecutarse de forma asincrónica.

Problema conocido: Activity.RegardingObjectId name value not set with plug-in (Problema conocido: Activity.RegardingObjectId name value not set with plug-in with plug-in (Problema conocido: Activity.RegardingObjectId name value not set

El síntoma más común de este problema es que el campo Con respecto a 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 . No se requiere la propiedad EntityReference.Name . 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 de preoperación de la canalización de eventos. Para más información, consulte 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 derivados de ActivityPointer heredan esta búsqueda. De forma predeterminada, incluyen Appointment, Chat, Email, Fax, Letter, PhoneCall, RecurringAppointmentMaster y las tablas personalizadas que se crearon como tipos de actividad. Para obtener más información, consulte 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 al recuperar el registro.

Solución alternativa

Hay dos formas de evitar 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