Handling SDK Errors Conditionally via HResult Codes in CRM 2015

Isaac Stephens, 28 January 2016

While developing plugins or console apps for Dynamics CRM that leverage the XRM SDK, you might find yourself wanting to handle specific errors, such as missing permissions, inserting duplicate keys, or any of the 2681 different web service error codes documented on MSDN and within the SDK (you can find these at https://msdn.microsoft.com/en-us/library/gg328182.aspx for reference).

While searching around online I found a lot of code examples that handled errors generically without paying attention to the error code, or relied upon printing the exception message to the user, but sometimes you need to use conditional logic to properly handle certain scenarios.

The MSDN article on handling exceptions for CRM 2015 (https://msdn.microsoft.com/en-us/library/gg327884.aspx) uses three different catches for FaultExceptions, System.TimeoutExceptions, and generic System.Exceptions. This is definitely useful and good practice, but it doesn’t handle specific errors under the FaultException class, which is something that CRM developers might deal with often. Microsoft’s code looks something like this:

try { _sdk.Create(entity); } catch (FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault> ex) { Console.WriteLine("Error: {0}", ex.Detail.Message); } catch (System.TimeoutException ex) { Console.WriteLine("Error: {0}", ex.Message); } catch (System.Exception ex) { Console.WriteLine("Error: {0}", ex.Message); }


However, inside each FaultException is a details container which holds, among other things, a specific error code for each possible fault. By accessing this property we can create conditional logic to deal with specific errors which arrive as FaultExceptions.

try { _sdk.Create(entity); } catch (FaultException<OrganizationServiceFault> ex) { switch (ex.Detail.ErrorCode) { // Missing privilege exception case -2147220943: Console.WriteLine("Missing privilege error: {0}", ex.Detail.Message); // Logic for handling missing privilege exceptions break; // Duplicate primary key exception case -2147220937: Console.WriteLine("Duplicate primary key error: {0}", ex.Detail.Message); // Logic for handling duplicate primary key exceptions break; default: Console.WriteLine("Error: {0}", ex.Detail.Message); break; } }

There’s also a class called ErrorCodes.cs included in the CRM SDK which enumerates each error code with a friendlier name – you can find the SDK on the Microsoft website (https://www.microsoft.com/en-us/download/details.aspx?id=50032) and the ErrorCodes.cs class in the folder SDK\SampleCode\CS\HelperCode\ErrorCodes.cs.
By adding this class to your project you could rewrite the code above like so:

switch (ex.Detail.ErrorCode) { // Missing privilege exception case ErrorCodes.PrivilegeDenied: Console.WriteLine("Missing privilege error: {0}", ex.Detail.Message); // Logic for handling missing privilege exceptions break; }

Depending on your preference, you might want to utilize the fully named error codes found in the ErrorCodes.cs class in order to improve readability, or you might be perfectly happy to use the raw error codes in their numerical form. Whichever method you choose will certainly be more useful than merely printing the error message without paying attention to the error code.