Skip to content

Commit

Permalink
Move handling of CRM rate limit exceptions into CrmEntityChangesServi…
Browse files Browse the repository at this point in the history
…ce (#875)
  • Loading branch information
gunndabad authored Oct 26, 2023
1 parent e98849b commit 9fdebe9
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 27 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System.ServiceModel;
using Microsoft.Xrm.Sdk;

namespace TeachingRecordSystem.Core.Dqt;

public static class ExceptionExtensions
{
public static bool IsCrmRateLimitException(this Exception exception, out TimeSpan retryAfter)
{
if (exception is FaultException<OrganizationServiceFault> fault &&
fault.Detail.ErrorDetails.TryGetValue("Retry-After", out var retryAfterObj) &&
retryAfterObj is TimeSpan retryAfterTs)
{
retryAfter = retryAfterTs;
return true;
}

retryAfter = default;
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,11 @@ public async IAsyncEnumerable<IChangedItem[]> GetEntityChanges(
request.PageInfo.PagingCookie = null;
continue;
}
catch (Exception ex) when (ex.IsCrmRateLimitException(out var retryAfter))
{
await Task.Delay(retryAfter, cancellationToken);
continue;
}

gotData |= response.EntityChanges.Changes.Count > 0;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
#nullable enable
using System.Data;
using System.ServiceModel;
using System.Text;
using Microsoft.ApplicationInsights;
using Microsoft.ApplicationInsights.DataContracts;
Expand Down Expand Up @@ -72,13 +70,6 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
_logger.LogWarning(ex, "Transient SQL exception thrown.");
continue;
}
catch (ProcessChangesException ex) when (ex.InnerException!.IsCrmRateLimitException(out var retryAfter))
{
_logger.LogWarning(ex, "Hit CRM rate limit error.");

await Task.Delay(retryAfter, stoppingToken);
continue;
}
catch (ProcessChangesException ex)
{
_logger.LogError(ex.InnerException, ex.Message);
Expand Down Expand Up @@ -153,7 +144,7 @@ await Parallel.ForEachAsync(
}
catch (Exception ex)
{
throw new ProcessChangesException($"Failed processing changes for '{entityType}' entity.", ex);
throw new ProcessChangesException(entityType, ex);
}
});
}
Expand Down Expand Up @@ -384,20 +375,3 @@ public ProcessChangesException(string entityType, Exception innerException)
private static string GetMessage(string entityType) =>
$"Failed processing changes for '{entityType}' entity.";
}

file static class ExceptionExtensions
{
public static bool IsCrmRateLimitException(this Exception exception, out TimeSpan retryAfter)
{
if (exception is FaultException<OrganizationServiceFault> fault &&
fault.Detail.ErrorDetails.TryGetValue("Retry-After", out var retryAfterObj) &&
retryAfterObj is TimeSpan retryAfterTs)
{
retryAfter = retryAfterTs;
return true;
}

retryAfter = default;
return false;
}
}

0 comments on commit 9fdebe9

Please sign in to comment.