How to troubleshoot a post-data migration error in a data migration related to Dynamics 365
Updated: Mar 25, 2021
I'm pretty sure that "troubleshoot" has to be a systematic approach if we need to resolve the CRM error in a short amount of time. Error means 3 things :
an undesirable behavior after a click by the user
a lack of expected functionality
a crash in the functionality after a click by the user
Problem: Description of CRM errors post-migration
When did a CRM error or exception occur during migration process ?
What type of CRM error or exception occurs when migrating data ?
Means or tools to address CRM errors or exceptions : Logs contents
Log generated by CRM platform
Log generated by the server (CRM Trace)
Log generated in the server (Event viewer)
"Tracking" tool of SQL queries generated through
Tool to decompile synchronous and asynchronous CRM services (.NET libraries)
Figuring out and resolving CRM errors
3 inclusive levels of "Troubleshooting"
CRM error handling and resolution process could be characterized by 3 levels of "Troubleshooting": extracting logs, tracking SQL Server queries, and finally, decompiling the D365 platform's native code source. These 3 levels of analysis should not be separated from each other but should instead be included in a comprehensive approach and considered complementary to each other.
1- Preliminary Step:
- Exécution du code de migration (SSIS package, etc...).
- Importer l’organisation CRM via le « Deployment Manager » (SDK Deployment)
- Exécuter les tests fonctionnels de type « CRUD » (Create, Read, Update et Delete) et
de type « Activation ».
2- Step 1: Retrieving the CRM log generated after the CRM error is displayed via the CRM interface.
3- Step 2: Extraction of CRM log generated in the server by D365 platform.
- Extracting ERROR errors if needed
- Extracting WARNING errors if needed
4- Step 3: Activate the CRM function "Trace" and restart the test.
5- Step 4: Extraction of CRM log from CRM Trace.
6- Step 5: Comparison and validation of the contents of the CRM "Trace" with previous extractions.
7- Step 6: Activate SQL Profiler and restart the test.
8- Step 7: Extracting SQL queries for the CRM database (CRM_MSCRM).
9- Step 8: Comparing and validating the contents of the "SQL Profiler" with previous extractions.
10- Step 9: Retrieving .NET (C#) code from the D365 Software Development Kit (SDK) via the Jet Brains decompiling tool.
11- Step 10: Extracting CRM native stored procedures from the CRM Organization (CRM_MSCRM) database.
As mentioned above, the steps are not exclusive, but complementary to one another. In addition, numbering highlights the order in which they are executed, even if it is not always necessary to extract the CRM native code from the database (step 10).
The further you go through the steps, the more you use "Troubleshooting" tools, and the more you advance in the resolution in depth.
We know that level 1 of "troubleshooting" is not enough to make sense of the error and even more so to link to SQL queries executed or queries executed by .NET code (via CRM SDK) during the transaction. That said, level 1 will at least be our starting point for the "troubleshooting" process. 2 scenarios are possible:
Scenario 1 - from level 1 (CRM client error as Log of platform) to level 3 (.Net CRM SDK used by CRM processes).
Scenario 2 - from level 1 (CRM client error as Log of platform) to level 2 (CRM Trace as Log of server) ; from level 2 to level 3 (.Net CRM SDK used by CRM processes).
Regardless of the type of error, the CRM trace and the SQL profiler play a decisive role:
The CRM trace provides access to the method of execution from the so-called "StackTrace" and the type of exception (e.g. CrmException); of course, the error code (e.g. -2147187957) can also be found there. As for the SQL profiler, it gives access to the SQL request executed but possibly to the stored procedure performed by the CRM service contracts (updaterequest, createrequest, etc.). In addition, the SQL profiler goes further by providing access to the SQL views used in the transaction.
As a result, the further you go in the level, the more generic the error can become. It is from level 2 that the generic error becomes a specific error.
Example : How to resolve the specific error related to the default business unit team ?
The error is of type CrmException and type "SystemFailure": ErrorCodes.ErrorMessages.Add((object) - 2147187957, (object) "Can't add members to the default business unit team"); ErrorCodes.ErrorTypes.Add((object) - 2147187957, (object) ErrorCodes.ErrorType.SystemFailure);
Step 1: Extract the method associated with the error on transaction from the "CRM Trace": "CheckPrivilegesAndAccess". Retrieving should allow us to determine the service generates the error, in this case "TeamServiceInternal".
Step 2: Extract the SQL execution query into the SQL Profiler (views, stored procedures if applicable): The stored procedure "p_... " is the stored procedure that searches for the privileges associated with the user that is logged in. The filtered views "..." and "..." are not negligible.
Step 3: Extract the "CheckPrivilegesAndAccess" method from the CRM SDK .NET library (Microsoft.Crm.ObjectModel). This method validates the privileges of the transaction user for each privilege associated with the "Team" associated with the transaction.
Regardless of whether an error is generic or specific and regardless of which entity the exception generated by the CRM platform is concerned, the dynamic library (DLL) "Microsoft.Crm.ObjectModel" plays a key role in the "troubleshooting" process.
The .NET library in question contains an extension for each native entity to the system (System User, Business Unit,Annotation...) for all service contracts executed by the platform and thus initiated by user action via the client interface (CreateRequest, UpdateRequest, SetStateRequest...).The execution of each extension contains validation actions that, in the case of failure, generate the "CRM Exception" type exception making the error a general or specific error (as emphasizing a specific exception).
For example, the System User entity has its own extension:
"SystemUserServiceInternal<T>". This extension is called by all functionalities accessible through the CRM interface ("create", "disable", "enable", etc.).
You can download my white paper : "Proving practical perspective on data migration - Dynamics 365".