public void ThrowNoNodesAttempted(RequestData requestData, List <PipelineException> seenExceptions)
        {
            var clientException = new TransportException(PipelineFailure.NoNodesAttempted, RequestPipelineStatics.NoNodesAttemptedMessage, (Exception)null);

            using (Audit(NoNodesAttempted))
                throw new UnexpectedTransportException(clientException, seenExceptions)
                      {
                          Request    = requestData,
                          AuditTrail = AuditTrail
                      };
        }
        public void BadResponse <TResponse>(ref TResponse response, IApiCallDetails callDetails, RequestData data,
                                            TransportException exception
                                            )
            where TResponse : class, ITransportResponse, new()
        {
            if (response == null)
            {
                //make sure we copy over the error body in case we disabled direct streaming.
                var s = callDetails?.ResponseBodyInBytes == null ? Stream.Null : _memoryStreamFactory.Create(callDetails.ResponseBodyInBytes);
                var m = callDetails?.ResponseMimeType ?? RequestData.MimeType;
                response = ResponseBuilder.ToResponse <TResponse>(data, exception, callDetails?.HttpStatusCode, null, s, m);
            }

            response.ApiCall.AuditTrail = AuditTrail;
        }
        public TransportException CreateClientException <TResponse>(
            TResponse response, IApiCallDetails callDetails, RequestData data, List <PipelineException> pipelineExceptions
            )
            where TResponse : class, ITransportResponse, new()
        {
            if (callDetails?.Success ?? false)
            {
                return(null);
            }

            var pipelineFailure = data.OnFailurePipelineFailure;
            var innerException  = callDetails?.OriginalException;

            if (pipelineExceptions.HasAny(out var exs))
            {
                pipelineFailure = exs.Last().FailureReason;
                innerException  = exs.AsAggregateOrFirst();
            }

            var statusCode = callDetails?.HttpStatusCode != null?callDetails.HttpStatusCode.Value.ToString() : "unknown";

            var resource = callDetails == null
                                ? "unknown resource"
                                : $"Status code {statusCode} from: {callDetails.HttpMethod} {callDetails.Uri.PathAndQuery}";

            var exceptionMessage = innerException?.Message ?? "Request failed to execute";

            if (IsTakingTooLong)
            {
                pipelineFailure = PipelineFailure.MaxTimeoutReached;
                Audit(MaxTimeoutReached);
                exceptionMessage = "Maximum timeout reached while retrying request";
            }
            else if (Retried >= MaxRetries && MaxRetries > 0)
            {
                pipelineFailure = PipelineFailure.MaxRetriesReached;
                Audit(MaxRetriesReached);
                exceptionMessage = "Maximum number of retries reached";

                var now         = _dateTimeProvider.Now();
                var activeNodes = _connectionPool.Nodes.Count(n => n.IsAlive || n.DeadUntil <= now);
                if (Retried >= activeNodes)
                {
                    Audit(FailedOverAllNodes);
                    exceptionMessage += ", failed over to all the known alive nodes before failing";
                }
            }

            exceptionMessage += $". Call: {resource}";
            if (response != null && _productRegistration.TryGetServerErrorReason(response, out var reason))
            {
                exceptionMessage += $". ServerError: {reason}";
            }

            var clientException = new TransportException(pipelineFailure, exceptionMessage, innerException)
            {
                Request    = data,
                Response   = callDetails,
                AuditTrail = AuditTrail
            };

            return(clientException);
        }