private async Task ExecuteAsync()

in iothub/device/src/Transport/Http/HttpClientHelper.cs [448:541]


        private async Task ExecuteAsync(
            HttpMethod httpMethod,
            Uri requestUri,
            Func<HttpRequestMessage, CancellationToken, Task> modifyRequestMessageAsync,
            Func<HttpResponseMessage, bool> isSuccessful,
            Func<HttpResponseMessage, CancellationToken, Task> processResponseMessageAsync,
            IDictionary<HttpStatusCode, Func<HttpResponseMessage, Task<Exception>>> errorMappingOverrides,
            CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            IDictionary<HttpStatusCode, Func<HttpResponseMessage, Task<Exception>>> mergedErrorMapping =
                MergeErrorMapping(errorMappingOverrides);

            using var msg = new HttpRequestMessage(httpMethod, requestUri);
            if (!_usingX509ClientCert)
            {
                string authHeader = await _authenticationHeaderProvider.GetPasswordAsync().ConfigureAwait(false);
                if (!string.IsNullOrWhiteSpace(authHeader))
                {
                    msg.Headers.Add(HttpRequestHeader.Authorization.ToString(), authHeader);
                }
            }

            msg.Headers.UserAgent.ParseAdd(_productInfo.ToString(UserAgentFormats.Http));

            if (modifyRequestMessageAsync != null)
            {
                await modifyRequestMessageAsync(msg, cancellationToken).ConfigureAwait(false);
            }

            // TODO: pradeepc - find out the list of exceptions that HttpClient can throw.
            HttpResponseMessage responseMsg;
            try
            {
                responseMsg = await _httpClientObj.SendAsync(msg, cancellationToken).ConfigureAwait(false);
                if (responseMsg == null)
                {
                    throw new InvalidOperationException(
                        $"The response message was null when executing operation {httpMethod}.");
                }

                if (isSuccessful(responseMsg))
                {
                    if (processResponseMessageAsync != null)
                    {
                        await processResponseMessageAsync(responseMsg, cancellationToken).ConfigureAwait(false);
                    }
                }
            }
            catch (AggregateException ex)
            {
                ReadOnlyCollection<Exception> innerExceptions = ex.Flatten().InnerExceptions;
                if (innerExceptions.Any(Fx.IsFatal))
                {
                    throw;
                }

                // Apparently HttpClient throws AggregateException when a timeout occurs.
                // TODO: pradeepc - need to confirm this with ASP.NET team
                if (innerExceptions.Any(e => e is TimeoutException))
                {
                    throw new IotHubCommunicationException(ex.Message, ex);
                }

                throw new IotHubException(ex.Message, ex);
            }
            catch (TimeoutException ex)
            {
                throw new IotHubCommunicationException(ex.Message, ex);
            }
            catch (IOException ex)
            {
                throw new IotHubCommunicationException(ex.Message, ex);
            }
            catch (HttpRequestException ex)
            {
                throw new IotHubCommunicationException(ex.Message, ex);
            }
            catch (OperationCanceledException)
            {
                throw;
            }
            catch (Exception ex) when (!ex.IsFatal())
            {
                throw new IotHubException(ex.Message, ex);
            }

            if (!isSuccessful(responseMsg))
            {
                Exception mappedEx = await MapToExceptionAsync(responseMsg, mergedErrorMapping).ConfigureAwait(false);
                throw mappedEx;
            }
        }