1
votes

I have added, as per user requirements, a custom field to the Quote Product entity (quotedetail) of CRM, allowing integration with our financial system (which is not currently in the scope of this problem). The field is named Summary Text Code, and is a lookup to a custom record type that exists purely for this purpose. In our development instance of CRM, this works perfectly, but in the Staging/UAT environment, all users (from the most limited up to SysAdmins) get the following error when attempting to save a record with a value set in this field:

Unhandled Exception: System.ServiceModel.FaultException`1[[Microsoft.Xrm.Sdk.OrganizationServiceFault, Microsoft.Xrm.Sdk, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]: An unexpected error occurred.Detail: 
<OrganizationServiceFault xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/xrm/2011/Contracts">
  <ErrorCode>-2147220970</ErrorCode>
  <ErrorDetails xmlns:d2p1="http://schemas.datacontract.org/2004/07/System.Collections.Generic">
    <KeyValuePairOfstringanyType>
      <d2p1:key>CallStack</d2p1:key>
      <d2p1:value xmlns:d4p1="http://www.w3.org/2001/XMLSchema" i:type="d4p1:string">   at Microsoft.Crm.Extensibility.VersionedPluginProxyStepBase.Execute(PipelineExecutionContext context)
   at Microsoft.Crm.Extensibility.Pipeline.Execute(PipelineExecutionContext context)
   at Microsoft.Crm.Extensibility.MessageProcessor.Execute(PipelineExecutionContext context)
   at Microsoft.Crm.Extensibility.InternalMessageDispatcher.Execute(PipelineExecutionContext context)
   at Microsoft.Crm.Extensibility.ExternalMessageDispatcher.ExecuteInternal(IInProcessOrganizationServiceFactory serviceFactory, IPlatformMessageDispatcherFactory dispatcherFactory, String messageName, String requestName, Int32 primaryObjectTypeCode, Int32 secondaryObjectTypeCode, ParameterCollection fields, CorrelationToken correlationToken, CallerOriginToken originToken, UserAuth userAuth, Guid callerId, Guid transactionContextId, Int32 invocationSource, Nullable`1 requestId, Version endpointVersion)
   at Microsoft.Crm.Extensibility.OrganizationSdkServiceInternal.ExecuteRequest(OrganizationRequest request, CorrelationToken correlationToken, CallerOriginToken callerOriginToken, WebServiceType serviceType, UserAuth userAuth, Guid targetUserId, Boolean traceRequest, OrganizationContext context, Boolean returnResponse)
   at Microsoft.Crm.Extensibility.OrganizationSdkServiceInternal.ExecuteRequest(OrganizationRequest request, CorrelationToken correlationToken, CallerOriginToken callerOriginToken, WebServiceType serviceType)
   at Microsoft.Crm.Extensibility.OrganizationSdkServiceInternal.Execute(OrganizationRequest request, CorrelationToken correlationToken, CallerOriginToken callerOriginToken, WebServiceType serviceType)</d2p1:value>
    </KeyValuePairOfstringanyType>
  </ErrorDetails>
  <Message>An unexpected error occurred.</Message>
  <Timestamp>2014-07-23T21:56:55.0044932Z</Timestamp>
  <InnerFault i:nil="true" />
  <TraceText i:nil="true" />
</OrganizationServiceFault>

A little Google-fu turned up the implication that this was a plugin problem. However, we have text file logging of our plugins, especially the one we have for Quote Products, and the plugin is not even entered in this situation.

What's even weirder is that the error does not occur when the value of this field is not set, so it's really hard for me to assert that I'm not at fault.

A little deeper digging into the event viewer and WER logs returns the following, more detailed error with a stack trace crossing the web service boundary:

Exception generated at: 7/23/2014 5:13:54 PM
Error Type: System.InvalidCastException
Error Message: Specified cast is not valid.
Error Stack Trace: 
    at SecurityAttributes..ctor(SecurityTraits traits, Guid objectId, Boolean allowNonUniqueRows, ArrayList attributes, ExecutionContext context)  ilOffset = 0xB1
    at SecurityAttributes..ctor(SecurityTraits traits, Guid objectId, ArrayList attributes, ExecutionContext context)  ilOffset = 0x7
    at SecurityExtension.GetSecurityAttributes(BusinessEntity entity, AttributeMetadata attribute, ExtensionEventArgs e, Relationship& relationship, SecurityTraits& traits)  ilOffset = 0x5E
    at SecurityExtension.CheckAppendAccess(BusinessEntity entity, ExtensionEventArgs e)  ilOffset = 0x29
    at SecurityExtension.PreUpdateHandlerAppendAppendToPrivilegeCheck(Object sender, SecurityTraits traits, SecurityAttributes attributes, ExtensionEventArgs e)  ilOffset = 0x28
    at SecurityExtension.PreUpdateHandler(ExtensionEventArgs e, Object sender)  ilOffset = 0x39
    at PreUpdateEventHandler.Invoke(Object sender, ExtensionEventArgs e)  ilOffset = 0xFFFFFFFF
    at BusinessProcessObject.UpdateWithPipelineAndExtensions(IBusinessEntity entity, ExecutionContext context)  ilOffset = 0x6F
    at QOIDetailService.Update(IBusinessEntity qoiDetail, ExecutionContext context, Boolean calculatePrice, Boolean checkState, BusinessEntity parentQoi)  ilOffset = 0x5B
    at QuoteDetailService.Update(IBusinessEntity quoteDetail, ExecutionContext context)  ilOffset = 0x78


Stack Frame: 

    at Pipeline.Execute(PipelineExecutionContext context)  ilOffset = 0x65
    at MessageProcessor.Execute(PipelineExecutionContext context)  ilOffset = 0x1C5
    at InternalMessageDispatcher.Execute(PipelineExecutionContext context)  ilOffset = 0xE4
    at ExternalMessageDispatcher.ExecuteInternal(IInProcessOrganizationServiceFactory serviceFactory, IPlatformMessageDispatcherFactory dispatcherFactory, String messageName, String requestName, Int32 primaryObjectTypeCode, Int32 secondaryObjectTypeCode, ParameterCollection fields, CorrelationToken correlationToken, CallerOriginToken originToken, UserAuth userAuth, Guid callerId, Guid transactionContextId, Int32 invocationSource, Nullable`1 requestId, Version endpointVersion)  ilOffset = 0x156
    at OrganizationSdkServiceInternal.ExecuteRequest(OrganizationRequest request, CorrelationToken correlationToken, CallerOriginToken callerOriginToken, WebServiceType serviceType, UserAuth userAuth, Guid targetUserId, Boolean traceRequest, OrganizationContext context, Boolean returnResponse)  ilOffset = 0x145
    at OrganizationSdkServiceInternal.ExecuteRequest(OrganizationRequest request, CorrelationToken correlationToken, CallerOriginToken callerOriginToken, WebServiceType serviceType)  ilOffset = 0x3D
    at OrganizationSdkServiceInternal.Execute(OrganizationRequest request, CorrelationToken correlationToken, CallerOriginToken callerOriginToken, WebServiceType serviceType)  ilOffset = 0x24
    at InprocessServiceProxy.ExecuteCore(OrganizationRequest request)  ilOffset = 0x34
    at PlatformCommand.XrmExecuteInternal()  ilOffset = 0xF6
    at UpdateCommand.Execute()  ilOffset = 0x7
    at DataSource.Update(EntityProxy entity, Boolean performDuplicateCheck, Guid auditingTransactionId, IOrganizationContext context)  ilOffset = 0x11
    at EntityProxy.Update(Boolean performDuplicateCheck, Guid auditingTransactionId)  ilOffset = 0x0
    at EntityProxy.Update(Boolean performDuplicateCheck)  ilOffset = 0x7
    at AppForm.SaveEntity(EntityProxy entity, FormEventId eventType, String redirectPath, Boolean performDuplicateCheck)  ilOffset = 0x2A
    at AppForm.Save(Boolean& gridRefreshCallbackAdded)  ilOffset = 0x47
    at AppForm.FormSaveEvent()  ilOffset = 0xD
    at AppForm.RaiseDataEvent(FormEventId eventId)  ilOffset = 0xCF
    at EndUserForm.Initialize(Entity entity)  ilOffset = 0x1F
    at CustomizableForm.Execute(Entity entity, FormDescriptor fd)  ilOffset = 0x62
    at QuoteDetailRecordPageHandler.ConfigureFormHandler()  ilOffset = 0x98
    at RecordPageHandler.ConfigureFormWrapper()  ilOffset = 0xC
    at GenericEventProcessor.RaiseEvent(String eventName)  ilOffset = 0x2D
    at PageManager.OnPreRender(EventArgs e)  ilOffset = 0x47
    at Control.PreRenderRecursiveInternal()  ilOffset = 0x54
    at Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)  ilOffset = 0x6D3
    at Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)  ilOffset = 0x3C
    at Page.ProcessRequest()  ilOffset = 0x14
    at Page.ProcessRequest(HttpContext context)  ilOffset = 0x33
    at CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()  ilOffset = 0x18D
    at HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)  ilOffset = 0x15
    at ApplicationStepManager.ResumeSteps(Exception error)  ilOffset = 0x10A
    at HttpApplication.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData)  ilOffset = 0x5C
    at HttpRuntime.ProcessRequestInternal(HttpWorkerRequest wr)  ilOffset = 0x16A
    at ISAPIRuntime.ProcessRequest(IntPtr ecb, Int32 iWRType)  ilOffset = 0x4B


Exception Data: 
    1: Key type: System.String, value: PluginTrace

Custom Message: Web Service Plug-in failed in SdkMessageProcessingStepId: a8cdbb1b-ea3e-db11-86a7-000a3a5473e8; EntityName: quotedetail; Stage: 30; MessageName: Update; AssemblyName: Microsoft.Crm.Extensibility.InternalOperationPlugin, Microsoft.Crm.ObjectModel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35; ClassName: Microsoft.Crm.Extensibility.InternalOperationPlugin; Exception: Unhandled Exception: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
   at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Web.Services.Protocols.LogicalMethodInfo.Invoke(Object target, Object[] values)
   at Microsoft.Crm.Extensibility.InternalOperationPlugin.Execute(IServiceProvider serviceProvider)
   at Microsoft.Crm.Extensibility.V5PluginProxyStep.ExecuteInternal(PipelineExecutionContext context)
   at Microsoft.Crm.Extensibility.VersionedPluginProxyStepBase.Execute(PipelineExecutionContext context)
Inner Exception: System.InvalidCastException: Specified cast is not valid.
   at Microsoft.Crm.BusinessEntities.SecurityAttributes..ctor(SecurityTraits traits, Guid objectId, Boolean allowNonUniqueRows, ArrayList attributes, ExecutionContext context)
   at Microsoft.Crm.BusinessEntities.SecurityAttributes..ctor(SecurityTraits traits, Guid objectId, ArrayList attributes, ExecutionContext context)
   at Microsoft.Crm.BusinessEntities.SecurityExtension.GetSecurityAttributes(BusinessEntity entity, AttributeMetadata attribute, ExtensionEventArgs e, Relationship& relationship, SecurityTraits& traits)
   at Microsoft.Crm.BusinessEntities.SecurityExtension.CheckAppendAccess(BusinessEntity entity, ExtensionEventArgs e)
   at Microsoft.Crm.BusinessEntities.SecurityExtension.PreUpdateHandlerAppendAppendToPrivilegeCheck(Object sender, SecurityTraits traits, SecurityAttributes attributes, ExtensionEventArgs e)
   at Microsoft.Crm.BusinessEntities.SecurityExtension.PreUpdateHandler(ExtensionEventArgs e, Object sender)
   at Microsoft.Crm.BusinessEntities.BusinessProcessObject.PreUpdateEventHandler.Invoke(Object sender, ExtensionEventArgs e)
   at Microsoft.Crm.BusinessEntities.BusinessProcessObject.UpdateWithPipelineAndExtensions(IBusinessEntity entity, ExecutionContext context)
   at Microsoft.Crm.ObjectModel.QOIDetailService.Update(IBusinessEntity qoiDetail, ExecutionContext context, Boolean calculatePrice, Boolean checkState, BusinessEntity parentQoi)
   at Microsoft.Crm.ObjectModel.QuoteDetailService.Update(IBusinessEntity quoteDetail, ExecutionContext context)

At this point I'm stumped. Not a single line of any error trace even goes through custom code, much less terminating at one, so this appears to be 100% CRM throwing a fit for reasons I cannot yet understand.

1

1 Answers

0
votes

The root cause appears to be a bug in the SSIS import job used to populate the lookup table; the job was using the wrong OrgID (or none at all) and so CRM was throwing a fit that the data being linked together weren't part of the same logical organization schema, even though they were in the same DB. Lesson learned.