Handling exceptions
This topic describes the exceptions that can be returned by xConnect and when they are likely to occur.
XdbUnavailableException
An XdbUnavailableException
exception indicates that the xConnect services is unavailable or that the request has timed out. The XdbCollectionUnavailableException
and XdbSearchUnavailableException
exceptions both inherit XdbUnavailableException
.
XdbExecutionException
xConnect throws an XdbExecutionException
when one or more operations in a batch fails to execute. Use client.GetOperations()
to select the specific operations that failed. The following example selects any operations that failed because the PhoneNumberList
facet already exists.
using Sitecore.XConnect.Collection.Model;
using Sitecore.XConnect.Operations;
using System;
using System.Threading.Tasks;
using System.Linq;
using Sitecore.XConnect;
using Sitecore.XConnect.Client;
namespace Documentation
{
public class CatchingExceptions
{
public async void ExampleAsync()
{
using (Sitecore.XConnect.Client.XConnectClient client = Sitecore.XConnect.Client.Configuration.SitecoreXConnectClientConfiguration.GetClient())
{
try
{
// Get contact
var reference = new Sitecore.XConnect.ContactReference(Guid.Parse("B9814105-1F45-E611-82E6-34E6D7117DCB"));
Task<Sitecore.XConnect.Contact> contactTask = client.GetAsync<Sitecore.XConnect.Contact>(reference, new ContactExecutionOptions(new Sitecore.XConnect.ContactExpandOptions(Sitecore.XConnect.Collection.Model.CollectionModel.FacetKeys.PhoneNumberList) { }));
Sitecore.XConnect.Contact contact = await contactTask;
// Update some properties on an existing facet
PhoneNumberList phoneNumberList = contact.PhoneNumbers();
phoneNumberList.PreferredKey = "Work";
phoneNumberList.PreferredPhoneNumber = new PhoneNumber("44", "55555555") { Extension = "1234" };
// Set updated facet
client.SetPhoneNumbers(contact, phoneNumberList);
// Submit changes
await client.SubmitAsync();
}
catch (XdbExecutionException ex)
{
// Get any operations that failed
var operations = ex.GetOperations(client)
.Where(x => x.Status == XdbOperationStatus.Failed);
foreach (var ops in operations)
{
if (ops is SetFacetOperation<PhoneNumberList>)
{
var phoneOps = ops as SetFacetOperation<PhoneNumberList>;
if (phoneOps.Result.Status == SaveResultStatus.AlreadyExists)
{
// LOG: This contact already has a PhoneNumberList facet
}
}
}
}
}
}
public void ExampleSync()
{
using (Sitecore.XConnect.Client.XConnectClient client = Sitecore.XConnect.Client.Configuration.SitecoreXConnectClientConfiguration.GetClient())
{
try
{
// Get contact
var reference = new Sitecore.XConnect.ContactReference(Guid.Parse("B9814105-1F45-E611-82E6-34E6D7117DCB"));
Contact contact = client.Get<Sitecore.XConnect.Contact>(reference, new ContactExecutionOptions(new Sitecore.XConnect.ContactExpandOptions(Sitecore.XConnect.Collection.Model.CollectionModel.FacetKeys.PhoneNumberList) { }));
// Update some properties on an existing facet
PhoneNumberList phoneNumberList = contact.PhoneNumbers();
phoneNumberList.PreferredKey = "Work";
phoneNumberList.PreferredPhoneNumber = new PhoneNumber("44", "55555555") { Extension = "1234" };
// Set updated facet
client.SetPhoneNumbers(contact, phoneNumberList);
// Submit changes
client.Submit();
}
catch (XdbExecutionException ex)
{
// Get any operations that failed
var operations = ex.GetOperations(client)
.Where(x => x.Status == XdbOperationStatus.Failed);
foreach (var ops in operations)
{
if (ops is SetFacetOperation<PhoneNumberList>)
{
var phoneOps = ops as SetFacetOperation<PhoneNumberList>;
if (phoneOps.Result.Status == SaveResultStatus.AlreadyExists)
{
// LOG: This contact already has a PhoneNumberList facet
}
}
}
}
}
}
}
}
-
The
Status
property is available on all operations -XdbOperationStatus.Failed
indicates a failed operation -
Result.Status
property is available on theSetFacetOperation
andAddContactIdentifier
operations - theResult
property may be null if a connection error prevented the operation from being executed -
Every operation has a nested
Exception
property
Retrying operations after an XdbExecutionException
You can retry a failed operation by adding it to the client using the client.RegisterOperation()
method and re-submitting the batch. This is useful if an operation failed due to a connectivity issue.
If an operation failed due to a concurrency issue, refer to the concurrency topic.
In the following example, an operation is retried after xConnect returned a XdbExecutionException
, indicating that one or more operations failed:
catch (XdbExecutionException ex)
{
// Get any operations that failed
var operations = ex.GetOperations(client)
.Where(x => x.Status == XdbOperationStatus.Failed);
foreach (var ops in operations)
{
client.RegisterOperation(ops);
}
await client.SubmitAsync();
}