diff --git a/src/Microsoft.Health.Fhir.Core.UnitTests/Features/Operations/Export/ExportJobTaskTests.cs b/src/Microsoft.Health.Fhir.Core.UnitTests/Features/Operations/Export/ExportJobTaskTests.cs index 87beb0f173..3805a8a759 100644 --- a/src/Microsoft.Health.Fhir.Core.UnitTests/Features/Operations/Export/ExportJobTaskTests.cs +++ b/src/Microsoft.Health.Fhir.Core.UnitTests/Features/Operations/Export/ExportJobTaskTests.cs @@ -534,6 +534,29 @@ public async Task GivenSearchHadIssues_WhenExecuted_ThenIssuesAreRecorded() Assert.True(_exportJobRecord.Issues.Contains(issue)); } + [Fact] + public async Task GivenSearchServiceThrowsRequestTimeoutException_WhenExecuted_ThenExceptionIsCaughtAndHandled() + { + // Arrange + string errorMessage = "The execution timeout expired while interacting with CosmosDB."; + _searchService.SearchAsync( + Arg.Any(), + Arg.Any>>(), + _cancellationToken, + true) + .Returns(x => + { + throw new RequestTimeoutException(errorMessage); + }); + + await _exportJobTask.ExecuteAsync(_exportJobRecord, _weakETag, _cancellationToken); + + Assert.NotNull(_lastExportJobOutcome); + Assert.Equal(OperationStatus.Failed, _lastExportJobOutcome.JobRecord.Status); + Assert.Contains(errorMessage, _lastExportJobOutcome.JobRecord.FailureDetails.FailureDetails); + Assert.Equal(HttpStatusCode.InternalServerError, _lastExportJobOutcome.JobRecord.FailureDetails.FailureStatusCode); + } + [Fact] public async Task GivenNumberOfSearch_WhenExecuted_ThenItShouldCommitOneLastTime() { diff --git a/src/Microsoft.Health.Fhir.CosmosDb.UnitTests/Features/Storage/CosmosResponseProcessorTests.cs b/src/Microsoft.Health.Fhir.CosmosDb.UnitTests/Features/Storage/CosmosResponseProcessorTests.cs index e9d88c151d..a23980b584 100644 --- a/src/Microsoft.Health.Fhir.CosmosDb.UnitTests/Features/Storage/CosmosResponseProcessorTests.cs +++ b/src/Microsoft.Health.Fhir.CosmosDb.UnitTests/Features/Storage/CosmosResponseProcessorTests.cs @@ -94,6 +94,14 @@ public async Task GivenAnExceptionWithRequestExceededStatusCode_WhenProcessing_T await Assert.ThrowsAsync(async () => await _cosmosResponseProcessor.ProcessErrorResponseAsync(CosmosResponseMessage.Create(response), CancellationToken.None)); } + [Fact] + public async Task GivenARequestTimeoutStatusCode_WhenProcessErrorResponseAsyncCalled_ThenRequestTimeoutExceptionShouldBeThrown() + { + ResponseMessage response = CreateResponseException("The execution timeout expired while interacting with CosmosDB.", HttpStatusCode.RequestTimeout); + + await Assert.ThrowsAsync(async () => await _cosmosResponseProcessor.ProcessErrorResponseAsync(CosmosResponseMessage.Create(response), CancellationToken.None)); + } + [Fact] public async Task GivenAnExceptionWithSpecificMessage_WhenProcessing_ThenExceptionShouldThrow() { diff --git a/src/Microsoft.Health.Fhir.CosmosDb/Features/Storage/CosmosResponseProcessor.cs b/src/Microsoft.Health.Fhir.CosmosDb/Features/Storage/CosmosResponseProcessor.cs index 88f09e43e4..d660952c83 100644 --- a/src/Microsoft.Health.Fhir.CosmosDb/Features/Storage/CosmosResponseProcessor.cs +++ b/src/Microsoft.Health.Fhir.CosmosDb/Features/Storage/CosmosResponseProcessor.cs @@ -88,6 +88,10 @@ public async Task ProcessErrorResponseAsync(HttpStatusCode statusCode, Headers h exception = new Microsoft.Health.Fhir.Core.Exceptions.CustomerManagedKeyException(GetCustomerManagedKeyErrorMessage(subStatusValue.Value)); } } + else if (statusCode == HttpStatusCode.RequestTimeout) + { + exception = new Microsoft.Health.Fhir.Core.Exceptions.RequestTimeoutException(Resources.CosmosDBRequestTimeout, exception); + } if (exception != null) { diff --git a/src/Microsoft.Health.Fhir.CosmosDb/Resources.Designer.cs b/src/Microsoft.Health.Fhir.CosmosDb/Resources.Designer.cs index 2d2efdea74..aed3a39996 100644 --- a/src/Microsoft.Health.Fhir.CosmosDb/Resources.Designer.cs +++ b/src/Microsoft.Health.Fhir.CosmosDb/Resources.Designer.cs @@ -96,6 +96,15 @@ internal static string CmkDefaultError { } } + /// + /// Looks up a localized string similar to The execution timeout expired while interacting with CosmosDB.. + /// + internal static string CosmosDBRequestTimeout { + get { + return ResourceManager.GetString("CosmosDBRequestTimeout", resourceCulture); + } + } + /// /// Looks up a localized string similar to _include:iterate and _revinclude:iterate are not supported.. /// diff --git a/src/Microsoft.Health.Fhir.CosmosDb/Resources.resx b/src/Microsoft.Health.Fhir.CosmosDb/Resources.resx index c3a0475cf5..9132f792c6 100644 --- a/src/Microsoft.Health.Fhir.CosmosDb/Resources.resx +++ b/src/Microsoft.Health.Fhir.CosmosDb/Resources.resx @@ -158,6 +158,9 @@ There was an error using the customer-managed key. + + + The execution timeout expired while interacting with CosmosDB. _include:iterate and _revinclude:iterate are not supported. @@ -173,5 +176,5 @@ Not able to execute a query. Retry the operation. - - \ No newline at end of file + +